Soutenez-nous

FAQ PHPConsultez toutes les FAQ

Nombre d'auteurs : 68, nombre de questions : 580, dernière mise à jour : 29 juillet 2013 

 
OuvrirSommaireFichiers et dossiersEnvoi / téléchargement de fichier

Un tel formulaire doit être constitué de deux parties : le formulaire HTML d'un côté et le traitement de la réponse du client d'autre part.

Le formulaire HTML permet de sélectionner le fichier à téléverser sur le serveur. Par exemple, vous pouvez utiliser un snippet de ce genre :

 
Sélectionnez
<form action="ftp.php" method="post" enctype="multipart/form-data">
    <input type="file" name="fichier" />
    <input type="submit" value="Téléverser" />
</form>

D'autre part, le script ftp.php, tel que précisé dans le formulaire, permettra la connexion au serveur FTP via les fonctions PHP de PHP. Lorsque le formulaire sera soumis, le fichier sera envoyé au serveur par HTTP et enregistré dans un dossier temporaire précisé dans le fichier de configuration php.ini.

ftp.php
Sélectionnez
<?php

define('CONFIG_SERVER',   'xxx');  // Adresse du serveur FTP
define('CONFIG_USERNAME', 'xxx');  // Nom d'utilisateur
define('CONFIG_PASSWORD', 'xxx');  // Mot de passe
define('CONFIG_TIMEOUT',  2);      // Délai de connexion, en secondes

if(! empty($_FILES['fichier']) && $_FILES['fichier']['error'] == UPLOAD_ERR_OK && is_uploaded_file($_FILES['fichier']['tmp_name']))
{
  $file = $_FILES['fichier']['tmp_name'];   // Le fichier téléversé
  $dest = '/' . $_FILES['fichier']['name']; // Sa destination

  $conn_id = ftp_connect(CONFIG_SERVER);   // Création de la connexion au serveur FTP

  if(empty($conn_id))
  {
    echo 'Échec de la connexion à ' . CONFIG_SERVER;
  }
  else
  {
    // Définition du délai de connexion
    ftp_set_option($conn_id, FTP_TIMEOUT_SEC, CONFIG_TIMEOUT);

    echo 'Connecté au serveur FTP.<br/>';
        
    // Identification avec le nom d'utilisateur et le mot de passe
    $login_result = ftp_login($conn_id, CONFIG_USERNAME, CONFIG_PASSWORD);

    if(!$login_result)
    {
      echo 'Échec d\'identification à ' . CONFIG_SERVER;
    }
    else
    {
      // Tentative de chargement sur le serveur FTP
      if(ftp_put($conn_id, $dest, $file, FTP_BINARY))
        echo 'Le fichier a été envoyé avec succès';
      else
        echo 'Problème lors de l'envoi du fichier';
    }
    // Fermeture de la connexion
    ftp_close($conn_id);
  }
}
Mis à jour le 8 mars 2011  par dourouc05

Lien : Tutoriel complet sur les formulaires en PHP, par Guillaume Rossolini
Lien : Tutoriel : Exploration de répertoires et liste des fichiers, par Hugo Étiévant

Il existe des types de fichiers qui sont normalement interprétés par le navigateur comme étant spécifiques à une application. La dite application va s'exécuter et ouvrir le fichier.

On souhaite ne pas ouvrir cette application et forcer l'enregistrement du fichier sur le disque du client. Pour forcer l'apparition de la boîte de dialogue "Enregistrer...", il faut envoyer les entêtes HTTP adéquats au navigateur.

Exemple :

 
Sélectionnez
<?php
$full_path = '...'; // chemin système (local) vers le fichier
$file_name = basename($full_path);
 
ini_set('zlib.output_compression', 0);
$date = gmdate(DATE_RFC1123);
 
header('Pragma: public');
header('Cache-Control: must-revalidate, pre-check=0, post-check=0, max-age=0');
 
header('Content-Tranfer-Encoding: none');
header('Content-Length: '.filesize($full_path));
header('Content-MD5: '.base64_encode(md5_file($full_path)));
header('Content-Type: application/octetstream; name="'.$file_name.'"');
header('Content-Disposition: attachment; filename="'.$file_name.'"');
 
header('Date: '.$date);
header('Expires: '.gmdate(DATE_RFC1123, time()+1));
header('Last-Modified: '.gmdate(DATE_RFC1123, filemtime($full_path)));
 
readfile($full_path);
exit; // nécessaire pour être certain de ne pas envoyer de fichier corrompu

?>

Il faut impérativement précéder ce code de vérifications sur la légitimité de la demande : le fichier est-il d'un type MIME que l'on autorise au téléchargement, est-il dans un dossier accessible par les visiteurs... Sans ces vérifications, vous exposeriez votre serveur entier au téléchargement par des internautes astucieux !

Mis à jour le 8 mars 2011  par Cyberzoide, Guillaume Rossolini, kankrelune

Lien : Comment récupérer le type d'un fichier ?

Il existe dans le fichier de configuration php.ini trois directives qui limitent la taille des fichiers que le serveur est capable de charger depuis le client :

  • upload_max_filesize fixe la taille maximum des fichiers chargés par les méthodes POST et PUT
  • post_max_size (supérieur à upload_max_filesize) fixe la taille maximum des fichiers chargés par la méthode POST
  • memory_limit (supérieur à post_max_size) fixe la taille de la mémoire du script

qui s'expriment en octets.

De plus, côté client, le formulaire HTML peut contenir le champ caché (input type=hidden) suivant : MAX_FILE_SIZE qui s'exprime lui aussi en octets. Ce dernier interdit au navigateur d'envoyer au serveur un fichier plus gros que MAX_FILE_SIZE octets.

Il existe enfin la directive max_input_time qui définit le temps maximal, en secondes, au script pour recevoir les données ; cela inclut le téléchargement du fichier. Pour de multiples fichiers, ou de gros fichiers, ou pour les utilisateurs sur de faibles connexions, la valeur par défaut de 60 secondes peut être dépassée.

Dans le cas où vous n'avez pas accès au php.ini, optez pour une connexion FTP...

Mis à jour le 5 août 2008  par Cyberzoide

Imaginons que vous créez un espace membre dont l'accès est sécurisé par login et mot de passe, et que vous proposiez à vos visteurs inscrits de télécharger des documents, par exemple :

 
Sélectionnez
http://www.monsite.fr/docs/unfichier.pdf

Il suffit que cette URL soit diffusée sur le Net pour que n'importe qui accède à votre fichier sans avoir à s'identifier. Une solution serait d'utiliser des fichiers de directives de configuration du serveur Apache : .htaccess et .htpasswd, mais vous vous retrouveriez avec deux systèmes d'authentification !

La solution passe par le stockage des chemins réels de vos fichiers dans une base de données et de passer un identifiant numérique à un script de téléchargement afin que celui-ci récupère le contenu du fichier en question.

Par exemple, l'URL devient :

 
Sélectionnez
http://www.monsite.fr/download.php?id=31

Le script download.php va chercher le chemin du fichier correspondant :

 
Sélectionnez
SELECT `path` FROM `file` WHERE `id`=$id

Et en retourne le contenu au navigateur :

 
Sélectionnez
<?php
if(!empty($_GET["id"])){
    $conn=mysql_connect('host','user','mot de passe');
    mysql_select_db('la bd',$conn);
    $res=mysql_query("select path from files where id=".$_GET["id"]) or die(mysql_error());
    if(mysql_num_rows($res)!=0){
        $row=mysql_fetch_object($res);
        header("Content-type: application/force-download");
        header("Content-Length: ".filesize($row->path));
        header("Content-Disposition: attachment; filename=".basename($row->path));
        readfile($row->path);
    }
}
?>

voir aussi : 'Comment créer une arborescence virtuelle ?' et 'Comment forcer le téléchargement d'un fichier ?'

Mis à jour le 5 août 2008  par Cyberzoide, stephaneey

Il n'est pas possible pour des raisons évidentes de sécurité de faire ce genre d'opération. PHP s'exécute côté serveur et rien ne peut être tenté côte client sans son accord.
Autrement dit, il n'est pas possible de mettre une valeur par défaut dans un champ HTML de type FILE.

Mis à jour le 5 août 2008  par BiD0uille

Il vous faut d'abord un fichier HTML pour le formulaire d'envoi.

 
Sélectionnez

<html>
<body>
<p>
<form method="post" enctype="multipart/form-data" action="uploadfile.php">
    <input type="file" name="userfile" size="50">
    <br>
    <input type="submit" value="Envoi">
</form>
</p>
</body>
</html>

Après avoir pressé sur le bouton "submit", le fichier est envoyé par le navigateur via le protocole HTTP et enregistré par le serveur dans le dossier des éléments temporaires (paramétrable dans le fichier de configuration php.ini).

Et maintenant le script PHP qui récupère le fichier pour le stockage dans le répertoire voulu.

 
Sélectionnez

<html>
<body>
<?php
$stock = 'mettre ici le chemin  on va stocker le fichier';

if (move_uploaded_file($_FILES['userfile']['tmp_name'], $stock.$_FILES['userfile']['name']))
{
    echo "Le fichier ".$_FILES['userfile']['name'].
            " a été téléchargé avec succès dans ".$stock;
}
?>
</body>
</html>

N'oubliez pas de vérifier les droits d'écriture sur le répertoire où on a stocké le fichier.

Attention également à la fonction move_uploaded_file : si le fichier de destination existe déjà, il sera écrasé

Le client ne peut pas sélectionner plusieurs fichiers dans la boîte de dialogue du navigateur. Pour cela, on utilise une astuce : plusieurs champs <INPUT FILE> :

 
Sélectionnez

Fichier 1 : <input type="file" name="userfile[]"><br>
Fichier 2 : <input type="file" name="userfile[]"><br>
Fichier 3 : <input type="file" name="userfile[]"><br>
etc

Dans votre script de récupération, vous aurez tout simplement l'index du fichier (démarrant à zéro) en troisième argument de tableau.

 
Sélectionnez

$_FILES['userfile']['name'][0]
Mis à jour le 5 août 2008  par BiD0uille
  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2003 Developpez.com Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.