IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Faire des vérifications pour un upload de photo


Sujet :

Langage PHP

  1. #1
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut Faire des vérifications pour un upload de photo
    Bonjour,

    voila je fais actuellement une page d'uploads de photos.

    Le problème c'est qu'aucune des vérifications ne fonctionnes !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    <?php
     
    if(!empty($_POST)){
     
    // Constantes
    $maxsize = "100000"; // Taille max en octets du fichier
    $maxwidth = "500"; // Largeur max de l'image en pixels
    $maxheight = "500"; // Hauteur max de l'image en pixels
     
    if ($_FILES['icone']['error'] > 0) $erreur = "Erreur lors du transfert";
     
    if ($_FILES['icone']['size'] > $maxsize) $erreur = "Le fichier est trop gros";
     
    $extensions_valides = array( 'jpg' , 'jpeg' , 'gif' , 'png' );
    //1. strrchr renvoie l'extension avec le point (« . »).
    //2. substr(chaine,1) ignore le premier caractère de chaine.
    //3. strtolower met l'extension en minuscules.
    $extension_upload = strtolower(  substr(  strrchr($_FILES['icone']['name'], '.')  ,1)  );
    if ( in_array($extension_upload,$extensions_valides) ) echo "Extension correcte";
     
    $image_sizes = getimagesize($_FILES['icone']['tmp_name']);
    if ($image_sizes[0] > $maxwidth OR $image_sizes[1] > $maxheight) $erreur = "Image trop grande";
     
    //Créer un identifiant difficile à deviner
      $nomcrypt = md5(uniqid(rand(), true));
     
    $nom = "uploads/{$nomcrypt}.{$extension_upload}";
    $resultat = move_uploaded_file($_FILES['icone']['tmp_name'],$nom);
    if ($resultat) echo "Transfert réussi";
    }
    ?>
     
    <?php require 'inc/header.php'; ?>
     
    <form method="post" action="" enctype="multipart/form-data">
         <label for="icone">Photo :</label><br />
         <input type="file" name="icone" id="icone" /><br />
         <input type="submit" name="submit" value="Envoyer" />
    </form>
    note : je n'ai aucun message d'erreur! les deux seuls messages que j'ai : Extension correcteTransfert réussi

  2. #2
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    Tes erreurs s'écrasent au fur et à mesure. Tu peux utiliser un tableau par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ($_FILES['icone']['error'] > 0) $erreur[] = "Erreur lors du transfert";
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  3. #3
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut
    oui j'ai essayé de trouver de moi même mais rien.. l'upload est difficile :/

    sinon j'ai aussi le code (qui fonctionne cette fois),
    je vais essayer de bosser dessus :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    <?php
     
    // Constantes
    define('MAX_SIZE', 100000);   // Taille max en octets du fichier
    define('WIDTH_MAX', 800);     // Largeur max de l'image en pixels
    define('HEIGHT_MAX', 800);    // Hauteur max de l'image en pixels
     
    // Tableaux de donnees
    $tabExt = array('jpg','gif','png','jpeg'); // Extensions autorisees
    $infosImg = array();
     
    // Variables
    $extension = '';
    $message = '';
    $nomImage = '';
     
    // Script d'upload
    if(!empty($_POST))
    {
      // On verifie si le champ est rempli
      if( !empty($_FILES['fichier']['name']) )
      {
        // Recuperation de l'extension du fichier
        $extension  = pathinfo($_FILES['fichier']['name'], PATHINFO_EXTENSION);
     
        // On verifie l'extension du fichier
        if(in_array(strtolower($extension),$tabExt))
        {
          // On recupere les dimensions du fichier
          $infosImg = getimagesize($_FILES['fichier']['tmp_name']);
     
          // On verifie le type de l'image
          if($infosImg[2] >= 1 && $infosImg[2] <= 14)
          {
            // On verifie les dimensions et taille de l'image
            if(($infosImg[0] <= WIDTH_MAX) && ($infosImg[1] <= HEIGHT_MAX) && (filesize($_FILES['fichier']['tmp_name']) <= MAX_SIZE))
            {
              // Parcours du tableau d'erreurs
              if(isset($_FILES['fichier']['error']) 
                && UPLOAD_ERR_OK === $_FILES['fichier']['error'])
              {
                // On renomme le fichier
                $nomImage = md5(uniqid()) .'.'. $extension;
     
                // Si c'est OK, on teste l'upload
                if(move_uploaded_file($_FILES['fichier']['tmp_name'], "uploads/$nomImage")) // Repertoire cible
                {
                  require_once 'inc/db.php';
     
                  // On insert dans la bdd
                  $req = $pdo->prepare("INSERT INTO photos SET idmbr = ?, nom = ?, date_ajout = CURDATE()");
                  $req->execute(array($user_id, $nomImage));
     
                  $_SESSION['flash']['success'] = 'Upload réussi en attente de validation';
                }
                else
                {
                  // Sinon on affiche une erreur systeme
                  $_SESSION['flash']['danger'] = 'Problème lors de l\'upload !';
                }
              }
              else
              {
                $_SESSION['flash']['danger'] = 'Une erreur interne a empêché l\'uplaod de l\'image';
              }
            }
            else
            {
              // Sinon erreur sur les dimensions et taille de l'image
              $_SESSION['flash']['danger'] = 'Erreur dans les dimensions de l\'image !';
            }
          }
          else
          {
            // Sinon erreur sur le type de l'image
            $_SESSION['flash']['danger'] = 'Le fichier à uploader n\'est pas une image !';
          }
        }
        else
        {
          // Sinon on affiche une erreur pour l'extension
          $_SESSION['flash']['danger'] = 'L\'extension du fichier est incorrecte !';
        }
      }
      else
      {
        // Sinon on affiche une erreur pour le champ vide
        $_SESSION['flash']['danger'] = 'Veuillez remplir le formulaire svp !';
      }
    }
    ?>
     
    <form enctype="multipart/form-data" action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" method="POST">
      <div class="form-group">
        <label for="fichier_a_uploader">Envoyer le fichier :</label>
        <input type="hidden" name="MAX_FILE_SIZE" value="<?php echo MAX_SIZE; ?>" />
        <input name="fichier" type="file" id="fichier_a_uploader">
        <p class="help-block">Example block-level help text here.</p>
      </div>
      <button type="submit" class="btn btn-primary">Envoyer</button>
    </form>

  4. #4
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Voir aussi : http://j-reaux.developpez.com/tutori...on-news/#L4-C2
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?php
    	// -------------------------------------
    	// extension du fichier uploadé (en minuscule)
    	$file_Extension 		= strtolower(pathinfo($_FILES['newsPhoto']['name'],PATHINFO_EXTENSION));
     
    	// Type MIME réel du fichier (important : évite les fichiers NON valides, dont l'extension a été renommée)
    //	$finfo 				= new finfo(FILEINFO_MIME_TYPE, NULL); // Retourne le type mime
    //	$file_MimeType 			= $finfo->file($_FILES['newsPhoto']['tmp_name']);
     
    	// (alternative, si la CLASS finfo n'est pas supportée)
    	$finfo 				= finfo_open(FILEINFO_MIME_TYPE); // Retourne le type mime à la extension mimetype
    	$file_MimeType 			= finfo_file($finfo, $_FILES['newsPhoto']['tmp_name']);
    	finfo_close($finfo);

  5. #5
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 380
    Points : 10 410
    Points
    10 410
    Par défaut
    Citation Envoyé par bndd24 Voir le message
    l'upload est difficile :/
    Oui parce que c'est un sujet spécifique et si l'upload par lui-même peut se faire en quelques lignes de code, la gestion des erreurs possibles est un sujet plus complexe.
    - Notamment dans ton code tu as oublié de vérifier le nom des fichiers pour les rendre compatibles avec le serveur.
    - Et puis si l'utilisateur dépasse la configuration "post_max_size" du serveur alors les variables $_POST et $_FILES seront nulles.

    Ensuite tu voudras peut-être pouvoir afficher la progression du téléchargement, et pourquoi pas faire afficher une vignette image si le fichier est une image, et peut être parfois permettre le téléchargement de gros fichiers ou l'upload multiple sans limitation. Et dans ces cas, il faudra passer par javascript pour avoir ces fonctionnalités et donc refaire ton code en conséquence...

    Pour dire que tu peux passer un bon moment avant d'avoir un module d'upload assez complet utilisable dans de multiples circonstances.

    C'est pour répondre à ce besoin que j'ai fais ce module d'upload. Il y a en autre des exemples d'upload et redimensionnements d'images (et même de recadrage - crop - avant l'upload). Tous les exemples sont fonctionnels.

    Je parle de redimensionnement car plutôt que de limiter la taille des images à l'entrée du formulaire comme tu le fais - ce qui est pénalisant pour le visiteur - ont préfère accepter n'importe quel fichier image et le redimensionner autoritairement en maximum hauteur et maximum largeur

  6. #6
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut
    jreaux62 : oui vérifier l'extension réelle, très important contre le hack !

    ABCIWEB : merci pour ton script, je vais jeter un œil mais je pense qu'il est assez "lourd" pour mon usage, mais pourquoi pas prendre des idées je te remercie.

  7. #7
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 380
    Points : 10 410
    Points
    10 410
    Par défaut
    Citation Envoyé par bndd24 Voir le message
    ABCIWEB : merci pour ton script, je vais jeter un œil mais je pense qu'il est assez "lourd" pour mon usage, mais pourquoi pas prendre des idées je te remercie.
    Tu peux t'en inspirer si tu veux, mais ce n'est pas le plus approprié puisque les fonctionnalités sont incluses dans le contexte d'une classe. Il serait sans doute plus avantageux de regarder des tutos spécifiques sur chaque fonctionnalité implémentée pour mieux comprendre son fonctionnement.

    Ensuite "lourd", bah c'est très relatif, 30Ko de javascript n'a jamais effrayé aucun navigateur et j'ai d'ailleurs testé le fonctionnement sans aucun problème sur des smartphones entrée de gamme à 60€. D'autre part un test de la réactivité d'une page contenant un exemple de formulaire (avec le code javascript) dans google speed donne un résultat de 99% pour mobiles et ordinateurs (100% après compression du html). Donc l'utilisation du module ne constitue pas d'inconvénient ni pour le fonctionnement ni pour le chargement de la page

    Enfin bon fais quand même attention à mes deux premières remarques dans mon premier message : il faut impérativement contrôler et éventuellement corrigé le nom du fichier en plus des extensions. Et la deuxième est que si on tente un téléchargement qui dépasse la limite du serveur, en l'état actuel ton code sera en vrac et aucune information ne sera envoyée pour avertir l'utilisateur (tes contrôles ne fonctionneront pas !).
    Le dernier problème sera peut-être peu fréquent, en fonction de la configuration de ton serveur et si tu n'autorise pas l'upload multiple, par contre le premier problème est très fréquent car bon nombre d'utilisateurs renomment souvent leurs fichiers avec des noms comportant des espaces ou des caractères spéciaux (non compatibles pour un accès serveur)

  8. #8
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut
    je vois..

    je pense qu'une fois mon mini-script d'upload de photos terminé, je te le donnerai pour validation héhé enfin si tu veux bien

  9. #9
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 380
    Points : 10 410
    Points
    10 410
    Par défaut
    je pense qu'une fois mon mini-script d'upload de photos terminé, je te le donnerai pour validation héhé
    Heu... mieux vaut dès le départ partir sur un code correct et pour cela rien ne vaut un petit tuto, par exemple ici pour le nom du fichier. On peut éventuellement garder plus de caractère utiles (cf module d'upload, classe php serveur, fichier "UploadAjaxABCIServeur.php"), mais le script du tuto est déjà une bonne base.

    Concernant la deuxième question tu peux gérer un dépassement du post_max_size comme ceci, en haut de ton code php (avant le test sur l'upload) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $derniere_erreur = error_get_last();
    if(isset($derniere_erreur) && $derniere_erreur['type'] == 2 && strpos($derniere_erreur['message'],'POST Content-Length') !== false)
    {
    header("Location:".$_SERVER['PHP_SELF']."?erreur_upload=1");
    exit;            
    }
    et dans ton code html
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <?php if(isset($_GET['erreur_upload']) && $_GET['erreur_upload']==1) 
    {
    echo 'Dépassement de la taille maximale du post supportée par le serveur';
    }
    Bien sûr il faut faire les tests en local sinon t'as pas fini de te prendre la tête à attendre (et même sur un local l'upload est pénible à tester puisqu'il faut charger un fichier à chaque fois). Pour info, tu obtiendras la valeur maximale supportée par le serveur avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo ini_get('post_max_size');
    Voilà avec ça (plus le contrôle des extensions) tu as le minimum vital côté php

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment faire des etats pour une application web ?
    Par ovh dans le forum Autres outils décisionnels
    Réponses: 6
    Dernier message: 06/07/2021, 03h25
  2. Réponses: 1
    Dernier message: 08/06/2008, 01h33
  3. Réponses: 7
    Dernier message: 02/11/2006, 02h15
  4. Comment faire des menus pour DVD-vidéo
    Par BigBenQ dans le forum Vidéo
    Réponses: 3
    Dernier message: 21/11/2005, 11h37
  5. Réponses: 63
    Dernier message: 13/10/2005, 12h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo