Chapitre 19. Gestion des chargements de fichier

Table des matières
Chargements de fichiers par méthode POST
Erreurs classiques
Chargement multiples de fichiers
Chargement par méthode PUT

Chargements de fichiers par méthode POST

PHP est capable de recevoir des fichiers émis par un navigateur conforme à la norme RFC-1867 (c'est à dire Netscape Navigator 3 ou supérieur, Microsoft Internet Explorer 3 avec un patch de Microsoft, ou supérieur sans le patch). Cette fonctionnalité permet de charger des fichiers texte binaire. Avec l'authentification et les fonctions de manipulation des fichiers, vous avez un contrôle total sur le chargement et la gestion des fichiers chargés.

Notez bien que PHP supporte aussi le chargement par la méthode PUT comme dans le navigateur Netscape Composer et les clients Amaya du W3C. Reportez vous au chapitre sur le support de la méthode PUT.

Un écran de chargement de fichiers peut être constitué en créant un formulaire de la manière suivante :

Exemple 19-1. Formulaire de chargement de fichier


<FORM ENCTYPE="multipart/form-data" ACTION="_URL_" METHOD=POST>
<INPUT TYPE="hidden" name="MAX_FILE_SIZE" value="1000">
Send this file: <INPUT NAME="userfile" TYPE="file">
<INPUT TYPE="submit" VALUE="Send File">
</FORM>
     
Le paramètre _URL_ doit pointer sur un fichier PHP. L'option MAX_FILE_SIZE cachée doit précéder le nom du fichier à charger, et représente la taille maximale du fichier à charger. La valeur est donnée en octets. Dans ce script, les valeurs suivantes doivent être définies pour assurer un chargement correct :

En PHP 3, les variables suivantes seront définies dans le script de destination, en cas de téléchargement réussi, et en supposant que register_globals est activé dans le fichier php.ini. Si track_vars est activé, elles seront aussi disponibles dans le dossier $HTTP_POST_VARS. Notez que les noms des variables suivantes supposent que nom du fichier téléchargé est 'userfile', comme présenté dans l'exemple ci-dessus.

Notez que "$userfile" prend la valeur qui est passée dans le champs INPUT de type TYPE=file. Dans l'exemple ci dessus, nous avons choisi de l'appeler "userfile".

En PHP 4, le comportement est légèrement différent, car c'est la variable d'environnement $HTTP_POST_FILES, qui contiendra les informations sur les fichiers téléchargés. Ces informations sont disponibles dans si track_vars est activé, mais track_vars est toujours activé dans les versions de PHP supérieure à la version 4.0.2.

Le contenu du tableau $HTTP_POST_FILES décrit ci dessous. Notez que l'on suppose ici que le nom du fichier téléchargé est 'userfile', comme présenté dans l'exemple ci-dessus :

$HTTP_POST_FILES['userfile']['name']

Le nom du fichier original sur la machine source.

$HTTP_POST_FILES['userfile']['type']

Le type MIME du fichier, si le navigateur a fourni cette information. Par exemple, "image/gif".

$HTTP_POST_FILES['userfile']['size']

La taille du fichier envoyé, en octets.

$HTTP_POST_FILES['userfile']['tmp_name']

Le nom temporaire du fichier qui sera chargé sur la machine serveur.

Les fichiers seront enregistrés par défaut dans le dossier des fichiers temporaires, à moins qu'un autre dossier n'ai été fourni avec la directive de configuration upload_tmp_dir du fichier php.ini. Le dossier par défaut du serveur peut être modifié grâce à la variable d'environnement TMPDIR, de l'utilisateur qui exécute PHP. Sa modificaion avec putenv() depuis un script PHP ne fonctionnera pas. Cette variable d'environnement peut aussi être utilisée pour s'assurer que d'autres opérations fonctionnent avec les fichiers téléchargés.

Exemple 19-2. Validation de fichiers téléchargés

Les exemples suivants fonctionnent sur les versions de PHP 3 supérieures à la version 3.0.16, et supérieures à la version 4.0.2 pour PHP 4. Reportez-vous à la section des fonctions pour étudier is_uploaded_file() et move_uploaded_file().


<?php
if (is_uploaded_file($userfile)) {
    copy($userfile, "/dossier/des/fichiers/telecharges/");
} else {
    echo "Attaque potentielle par fichier téléchargé : fichier '$userfile'.";
}
/* ...ou... */
move_uploaded_file($userfile, "/dossier/des/fichiers/telecharges");
?>
     

Pour les versions plus anciennes de PHP, vous devrez faire quelques chose comme :

Note : Cela ne fonctionnera PAS avec les versions de PHP 4 supérieure à 4.0.2. Cela repose sur des fonctionnalités internes à PHP qui on évoluée après cette version.


<?php
/* Test du fichier téléchargé. */
function is_uploaded_file($filename) {
    if (!$tmp_file = get_cfg_var('upload_tmp_dir')) {
        $tmp_file = dirname(tempnam('', ''));
    }
    $tmp_file .= '/' . basename($filename);
    /* L'utilisateur peut avoir un slash final dans php.ini... */
    return (ereg_replace('/+', '/', $tmp_file) == $filename);
}
if (is_uploaded_file($userfile)) {
    copy($userfile, "/place/to/put/uploaded/file");
} else {
    echo "Attaque potentielle par fichier téléchargé : fichier '$userfile'.";
}
?>
     

Le script PHP qui recoit le fichier chargé doit pouvoir gérer le fichier de manière appropriée. Vous pouvez utiliser la variable $file_size pour recaler tous les fichiers qui sont trop gros ou trop petit. Vous pouvez utiliser la variable $file_type pour recaler les fichiers qui n'ont pas le bon type. Quelque soient les actions, ce script doit pouvoir supprimer le fichier du dossier temporaire, ou le déplacer ailleurs.

Le fichier sera automatiquement effacé du fichier temporaire à la fin du script, si il n'a pas été déplacé ou renommé.