D'accord, je suis totalement nouveau dans ce domaine et j'ai lu quelques tutoriels. J'ai constaté que lors du téléchargement de fichiers dans PHP), il les stocke dans un emplacement temporaire.
$file_temp=$_FILES['file']['tmp_name'];
$file_loc="Upload".$file_name;
move_uploaded_files($file_temp,$file_loc);
Maintenant, pourquoi PHP n'autorise pas le téléchargement de fichiers directement à l'emplacement souhaité? Pourquoi sont-ils stockés dans un emplacement temporaire avec une extension .tmp et quel avantage retirons-nous de cette stratégie?
Bonne question. La réponse courte est que PHP doit traiter la requête HTTP entière - en remplissant $_POST
Avec des données, et $_FILES
Au besoin - avant de donner le contrôle à votre script. Étant donné que votre script ne prend le contrôle qu'après après le traitement , il est impossible d'indiquer à PHP où placer les données de ce fichier.
Mais pourquoi PHP fait-il cela? Eh bien, regardons un HTTP POST avec les données du fichier :
POST /upload?upload_progress_id=12344 HTTP/1.1
Host: localhost:3000
Content-Length: 1325
Origin: http://localhost:3000
... other headers ...
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryePkpFF7tjBAqx29L
------WebKitFormBoundaryePkpFF7tjBAqx29L
Content-Disposition: form-data; name="MAX_FILE_SIZE"
100000
------WebKitFormBoundaryePkpFF7tjBAqx29L
Content-Disposition: form-data; name="uploadedfile"; filename="hello.o"
Content-Type: application/x-object
... contents of file goes here ...
------WebKitFormBoundaryePkpFF7tjBAqx29L--
Notez que le contenu de la demande est un document codé en plusieurs parties, avec des champs de formulaire intercalés entre les données du fichier. Dans cet exemple particulier, le champ de formulaire apparaît avant les données du fichier. Cependant, il est possible - voire probable - que des données de formulaire se produisent après des données de fichier.
Donc, pour garantir que PHP peut vous donner tout les données $_POST
, PHP doivent traiter l'intégralité de la demande. Donc, il pourrait tout aussi bien compléter le super-global $_FILES
Tant qu'il est là.
Maintenant, PHP pourrait conserver ces données de fichier en mémoire, mais cela pourrait vraiment être une mauvaise idée. Pensez à ce qui se produirait si PHP avait besoin de stocker un fichier de 100 MiB téléchargé par un utilisateur. Soudainement, vous avez une augmentation de 100 Mio dans le flux RSS de votre processus Apache, ce qui n’est vraiment pas très bon - Apache pourrait être ulimit
ed pour ne pas avoir trop d’espace, ou Apache pourrait être échangé: pour vos utilisateurs angoisse. Donc, PHP fait la meilleure chose à faire: mettez ce fichier reçu dans un fichier temporaire.
Vous pourriez vous demander pourquoi on ne peut pas dire à PHP quel fichier doit placer les données de fichier entrantes en premier, vous n'avez donc pas à les déplacer. Eh bien, c'est un problème de démarrage: PHP n'a pas encore cédé le contrôle au script, le script ne peut donc pas indiquer PHP où placer le fichier. Ainsi, PHP fait de son mieux: placez les données du fichier dans un fichier temporaire.
Maintenant, vous pouvez conserver ces données de fichier sur un disque RAM, pour plus de rapidité si vous le souhaitez. C'est une bonne approche si les coûts d'infrastructure ne vous gênent pas (par exemple, maintenir la configuration du disque RAM). Mais notez que ce n'est pas comme si PHP le maintenait dans RAM lui-même: dans ce scénario, le processus de conteneur PHP (généralement Apache ou un autre serveur Web) doit avoir le tas pour contenir le fichier (ce qui pourrait ne pas être le cas). Dans ce scénario, le disque RAM est géré par le noyau.
- Sur la plupart des plates-formes, les déplacements de fichiers sont atomiques, mais pas les écritures de fichiers (surtout si vous ne pouvez pas écrire toutes les données en une fois). Donc, si vous avez le modèle producteur/consommateur typique (un processus produit des fichiers, l’autre surveille un répertoire et récupère tout ce qu’il trouve), en écrivant d’abord dans un dossier temporaire puis en se déplaçant à l’emplacement réel, le consommateur ne peut jamais voir dossier inachevé.
- Si le processus qui écrit le fichier tombe à mi-chemin, vous avez un fichier endommagé sur votre disque. S'il s'agit d'un emplacement réel, vous devez le nettoyer vous-même, mais s'il s'agit d'un emplacement temporaire, le système d'exploitation s'en chargera. Si le fichier est créé lors de l'exécution d'un travail de sauvegarde, celui-ci peut récupérer un fichier incomplet. Les répertoires temporaires étant généralement exclus des sauvegardes, le fichier ne sera inclus qu'une fois déplacé vers la destination finale.
- Le répertoire temporaire peut se trouver sur un système de fichiers rapide mais volatil (par exemple, un disque virtuel), ce qui peut être avantageux pour le téléchargement de plusieurs morceaux du même fichier en parallèle ou le traitement sur place du fichier avec de nombreuses recherches. De plus, les répertoires temporaires ont tendance à causer plus de fragmentation que les répertoires avec des lectures, écritures et suppressions moins fréquentes, et le fait de conserver le répertoire temporaire sur une partition séparée peut aider à limiter la fragmentation des autres partitions.
Deux raisons supplémentaires:
Si vous décidez de ne pas accepter le fichier pour une raison quelconque, il est stocké dans un emplacement temporaire et sera probablement supprimé à un moment donné.
Sécurité. Disons que PHP a été configuré pour charger dans un répertoire accessible par le Web tel que/images. Quelqu'un pourrait télécharger une sorte de fichier de piratage puis l'exécuter. En plaçant d'abord les fichiers dans un répertoire temporaire (qui généralement pas accessible sur le Web), PHP vous permet d’examiner le fichier en premier. Par exemple, en traitant les images pour supprimer tout commentaire pouvant contenir du code PHP.