Uploader en PHP

Deux machines (client et serveur) reliées par une connexion réseau (à savoir même une connexion Internet), ou un serveur web tel que Apache est installé sur la machine serveur. Les deux machines peuvent échanger des fichiers l’un vers l’autre.

upload

L’upload est l’opération qui consiste à envoyer un fichier depuis la machine du visiteur vers le serveur.

1) Configuration :

Durant ce tutoriel, on va essayer d’uploader des fichiers via PHP, mais pas tout de suite car il faut prendre en considération certain paramètre de configuration sur le fichier « php.ini ». Sous Windows, ce fichier existe dans « C :\windows », sinon sous linux, il existe dans le dossier « lib », par exemple si PHP est installé dans « /usr/local/php » alors le chemin est : « /usr/local/php/lib/php.ini ».

Les paramètres à vérifier sur le « php.ini » sont :

file_uploads(boolean) : Autorise ou non le chargement de fichiers par HTTP.

upload_tmp_dir(String) : Le répertoire temporaire utilisé pour stocker les fichiers lors du chargement. Si non spécifié, PHP utilisera celui par défaut du système.

upload_max_filesize(Integer) : La taille maximale en octets d’un fichier à charger. Sa valeur est indiquée en octet (entier), sinon on peut utiliser la notation sténographique.

post_max_size(Integer) : La taille maximale des données reçues par la méthode POST. Cette option affecte également les fichiers chargés.

memory_limit(integer) : La mémoire limite qu’un script est autorisé à allouer.

max_input_time(Integer) : La durée maximale pour analyser les données d’entrée, via POST, GET et téléchargement de fichier.

max_execution_time (Integer) : Le temps maximal d’exécution d’un script, en Seconde.

2) Le Formulaire

Afin que l’utilisateur puisse transférer des fichiers, il doit le choisir n’est ce pas? Donc on va faire l’appel au formulaire, mais de quelle manière on doit utiliser le formulaire pour l’upload des fichiers ?
Lorsqu’on souhaite envoyer un fichier au serveur par formulaire, on doit préciser l’enctype, c’est à dire le type d’encodage du fichier. L’enctype à utiliser est multipart/form-data. C’est très important car si on ne le fait pas, on ne pourra pas uploader le fichier !

Donc le formulaire vide aura la forme suivante :

<form action="upload.php" enctype="multipart/form-data" method="POST"> <!–– Le contenu du formulaire est à placer ici ––>
</form>

Pour permettre à l’utilisateur de choisir le fichier, on va placer un champ de type « file » :

<input name="userfile" type="file" />

Surtout il ne faut pas permettre à l’utilisateur d’uploader des fichiers de grande taille. J’espère que vous vous rappelez toujours du paramètre « upload_max_filesize », ce paramètre est général pour tout script se trouvant dans le serveur. Pour une taille bien spécifique (toujours inferieure à upload_max_file), on va placer avant le champ « file » un champ caché « hidden » qui aura «MAX_FILE_SIZE » comme nom (il faut respecter ce nom).

<input name="MAX_FILE_SIZE" type="hidden" value="1000000" />

Donc le formulaire aura la forme suivante :

<form action="uploder.php" enctype="multipart/form-data" method="post"> <input name="MAX_FILE_SIZE" type="hidden" value="1000000" />
Envoyez ce fichier : <input name="userfile" type="file" />
<input type="submit" value="Envoyer le fichier" /></form>

3) Récupération et Traitement du fichier

Lorsque le formulaire est envoyé, le fichier est envoyé sur le serveur dans un répertoire temporaire. Une fois que le script php en action est terminé, le fichier envoyé est supprimé du répertoire temporaire. Il faut donc traiter/copier ce fichier avant.
Pour cela, PHP fournie la variable globale « $_FILES » sous forme d’un tableau associatif qui contient toutes les informations du fichier uploadé.
Ces informations sont stocké dans « $_FILES » comme suit :

$_FILES[‘user_file’][‘name’] : Le nom original du fichier, tel que sur la machine du client.

$_FILES[‘user_file’][‘type’] : Le type MIME du fichier. Par exemple : « application/pdf ».

$_FILES[‘user_file’][‘size’] : La taille, en octets, du fichier téléchargé.

$_FILES[‘user_file’][‘tmp_name’] : Le nom temporaire du fichier qui sera chargé sur la machine serveur.

$_FILES[‘user_file’][‘error’] : Le code d’erreur associé au téléchargement de fichier. (Voir les erreurs sur le manuel du PHP).

Après s’assurer du fichier uploadé, il faut le copier dans un répertoire bien déterminé avant sa suppression. Pour se faire on fait appel à la fonction « bool move_uploaded_file ( string $filename , string $destination ) ». Cette fonction renvoie TRUE si elle a correctement fonctionné sinon FALSE.

N.B :

On doit néanmoins donner le droit d’écriture à PHP sur le dossier destination. (CHMOD is your friend)

Voici donc un code qui marche bien avec le premier formulaire.

<?php
    $uploaddir = ‘./uploads/’;
    $uploadfile = $uploaddir . basename($_FILES[‘
userfile‘][‘name‘]);
    echo ‘
<pre>;
    if (move_uploaded_file($_FILES[‘userfile’][‘tmp_name’], $uploadfile))
    {
    echo « Le fichier est valide, et a été téléchargé avec succès.\n »;
    } else {
    echo « Attaque potentielle par téléchargement de fichiers.\n »;
    }
    echo « Voici quelques informations de cette opération : \n »;
    print_r($_FILES);
    echo ‘</pre>’;
    ?>

4) Sécurité

Pour ce qui concerne la sécurité on va se limiter dans cet article à deux type de sécurité : le type de fichier et sa taille.

Problème 1 :
Un génie essaie d’uploader un fichier PHP qui permet de récupérer des informations depuis notre serveur.
On peut contourner ce problème par la vérification de l’extension. Cet exemple illustre une utilisation de ce principe dans l’envoie des CVs sous format pdf ou doc :

<?php
$dossier = ‘./uploads/’;
$fichier = basename($_FILES[‘cv’][‘name’]);
$extensions = array(‘.doc’, ‘.pdf’);
$extension = strrchr($_FILES[‘cv’][‘name’], ‘.’); //récupération de l’extension du fichier envoyé
//Début des vérifications de sécurité…
if(!in_array($extension, $extensions)) //Si l’extension n’est pas dans le tableau
{
$erreur = ‘Vous devez uploader un CV sous format pdf ou doc.’;
}
if(!isset($erreur)) //S’il n’y a pas d’erreur, on upload
{
if(move_uploaded_file($_FILES[‘cv’][‘tmp_name’], $dossier . $fichier))
//Si la fonction renvoie TRUE, c’est que ça a fonctionné…
{
echo ‘Upload effectué avec succès !’;
}
else //Sinon (la fonction renvoie FALSE).
{
echo ‘Echec de l\’upload !’;
}
}
else
{
echo $erreur;
}
?>

Problème 2 :
Son gémeau, plus malin, peut enregistrer le formulaire sur son disque et modifier la valeur du champ « MAX_FILE_SIZE ».
Egalement on peut contourner ce problème par la vérification de la taille du fichier uploadé, comme dans l’exemple suivant :

<?php
$dossier = ‘./uploads/’;
$fichier = basename($_FILES[‘
cv‘][‘name‘]);
$taille_maxi = 100000;
$taille = filesize($_FILES[‘
cv‘][‘tmp_name‘]);
if($taille>$taille_maxi)
{
$erreur = ‘
Le fichier est trop gros…’;
}
if(!isset($erreur)) //S’il n’y a pas d’erreur, on upload
{
if(move_uploaded_file($_FILES[‘cv’][‘tmp_name’], $dossier . $fichier))
//Si la fonction renvoie TRUE, c’est que ça a fonctionné…
{
echo ‘Upload effectué avec succès !’;
}
else //Sinon (la fonction renvoie FALSE).
{
echo ‘
Echec de l\’upload !;
}
}
else
{
echo $erreur;
}
?>

C’est la fin de ce tutoriel, j’espère que maintenant vous pouvez développer vos propres codes pour l’upload des fichiers en PHP.

A propos de l'auteur

Faut il vraiment porter des lunettes, pour travailler la nuit, sur un terminal vert sur noire, pour être Geek pour devenir root ?