Chapitre 18. Gestion des chargements de fichier

Table des matières
Chargements de fichiers par méthode POST
Explication sur les messages d'erreurs de chargement de fichiers
Erreurs classiques
Télécharger plusieurs fichiers simultanément
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 textes ou binaires. 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.

Notes de configuration : Voir aussi les directives file_uploads, upload_max_filesize, upload_tmp_dir et post_max_size, dans php.ini

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 18-1. Formulaire de chargement de fichier

<FORM ENCTYPE="multipart/form-data" ACTION="_URL_" METHOD="POST">
<INPUT TYPE="hidden" name="MAX_FILE_SIZE" value="1000">
Envoyez ce fichier : <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.

Avertissement

Le champs MAX_FILE_SIZE est là à titre de conseil au navigateur. Il est très facile de contourner cette restriction. Ne comptez pas sur le respect de cette configuration par le navigateur! La configuration de PHP sur la taille maximale à respecter (upload_max_filesize) ne peut être contournée, elle.

Les variables définies après un téléchargement de fichiers diffèrent beaucoup de version en version. La variable $_FILES existe depuis PHP 4.1.0. Le tableau $HTTP_POST_FILES existe depuis PHP 4.0.0. Ces tableaux contiennent toutes les données sur les fichiers téléchargés. L'utilisation de la variable $_FILES est recommandée. Si la directive PHP register_globals vaut on, les variables reliées existeront aussi. register_globals vaut par défaut off depuis PHP 4.2.0.

Le contenu du tableau $_FILES est détaillé dans notre exmple ci-dessous. Notez que l'un suppose que le nom de la variable du fichier téléchargé est userfile, tel que défini dans le formulaire ci-dessus.

$_FILES['userfile']['name']

Le nom original du fichier, tel que sur la machine du client web.

$_FILES['userfile']['type']

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

$_FILES['userfile']['size']

La taille, en octets, du fichier téléchargé.

$_FILES['userfile']['tmp_name']

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

$_FILES['userfile']['error']

Le code d'erreur error code associaé au téléchargement de fichier. ['error'] a été introduit en PHP 4.2.0

Note : Dans les versions de PHP antérieure à la version 4.1.0, la variable $_FILES s'appelait $HTTP_POST_FILES et ce n'était pas une variable autoglobale comme l'est $_FILES. PHP 3 ne supporte pas $HTTP_POST_FILES.

Lorsque register_globals vaut on dans le php.ini, des variables supplémentaires sont rendues disponibles. Par exemple $userfile_name vaut $_FILES['userfile']['name'], $userfile_type vaut $_FILES['userfile']['type'], etc... Gardez à l'esprit que depuis PHP 4.2.0, register_globals vaut off par défaut. Il n'est pas prudent de supposer que cette directive vaut on.

Le fichier téléchargé sera stocké temporairement dans le dossier temporaire du système, à moins qu'un autre dossier soit fourni avec la directive upload_tmp_dir du php.ini. Le dossier par défaut du serveur peut être changé dans l'environnement via la variable TMPDIR. Modifier la valeur de cette variable avec la fonction putenv() dans un script PHP sera sans effet. Cette variable d'environnement peut aussi être utilisée pour s'assurer que d'autres opérations fonctionnent aussi sur les fichiers téléchargés.

Exemple 18-2. Validation de téléchargement de fichiers

Les exemples ci-dessous sont valables avec les versions de PHP plus récentes que la 4.0.2. Voyez les fonctions is_uploaded_file() et move_uploaded_file().

<?php 
// En PHP < 4.1.0, $HTTP_POST_FILES doit &ecirc;tre utilis&eacute; 
//    &agrave; la place de $_FILES.
// En PHP plus ancien que 4.0.3, utilisez copy() et is_uploaded_file() 
//    &agrave; la place de move_uploaded_file

$uploaddir = '/var/www/uploads/';

print "<pre>";
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploaddir . $_FILES['userfile']['name'])) {
    print "Le fichier est valide, et a &eacute;t&eacute; t&eacute;l&eacute;charg&eacute; 
           avec succ&egrave;s. Voici plus d'informations :\n";
    print_r($_FILES);
} else {
    echo "Attaque par upload potentielle. Voici plus d'informations :\n";
    print_r($_FILES);
}
?>

Le script PHP qui reçoit 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 petits. Vous pouvez utiliser la variable $file_type pour recaler les fichiers qui n'ont pas le bon type. Quelques soient les actions, ce script doit pouvoir supprimer le fichier du dossier temporaire, ou le déplacer ailleurs. Depuis PHP 4.2.0, vous pouvez utiliser l'information dans $_FILES['userfile']['error'] et adapter votre politique en fonction des code d'erreur. Quelque soit votre politique, vous devriez soit effacer le fichier du dossier temporaire, soit le déplacer.

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