Chargement par méthode PUT
PHP supporte la méthode HTTP PUT utilisée par
les navigateurs pour y stocker des fichiers sur un serveur.
Les requêtes de type PUT sont beaucoup plus simples que
les chargements de fichiers en utilisant le type POST, et elles
ressemblent à :
Normalement, cela signifie que le client distant souhaite sauver
les données qui suivent dans le fichier : /path/filename.html
de l'arborescence web. Ce n'est évidemment pas très
sécurisé de laisser Apache ou PHP écraser n'importe
quel fichier de l'arborescence. Pour éviter ceci, il faut d'abord
dire au serveur qu'un script PHP donné doit gérer
la requête. Avec Apache, il y a une directive pour cela :
Script. Elle peut être placée
n'importe où dans le fichier de configuration d'Apache.
En général, les webmestres la placent dans le bloc
<Directory>, ou peut-être dans le bloc
<VirtualHost>.
La ligne suivante fera très bien l'affaire :
Elle indique à Apache qu'il doit envoyer les requêtes
de chargement par méthode PUT au script
put.php. Bien entendu,
cela présuppose que PHP a été activé pour qu'il
prenne en charge les fichiers de type .php,
et que PHP est actif. La ressource de destination pour toutes les
requêtes PUT de ce script doit être le script lui-même, et non le
nom du fichier que le fichier téléchargé doit avoir.
Avec PHP, on pourrait faire quelque chose comme ce qui suit
dans le fichier put.php. Ceci va copier le contenu
du fichier téléchargé dans le fichier
myputfile.ext sur le serveur.
Il est probablement souhaitable d'effectuer quelques vérifications et/ou
identifier l'utilisateur avant d'effectuer cette copie de fichier.
Exemple #1 Sauvegarde de fichiers HTTP PUT
<?php
/* Les données PUT arrivent du flux */
$putdata = fopen("php://input", "r");
/* Ouvre un fichier pour écriture */
$fp = fopen("myputfile.ext", "w");
/* Lecture des données, 1 Ko à la fois et écriture dans le fichier */
while ($data = fread($putdata, 1024))
fwrite($fp, $data);
/* Fermeture du flux */
fclose($fp);
fclose($putdata);
?>
micronix at gmx dot net ¶15 years ago
Hello PHP World After many Hours of worryness :=)
I have found the Solution for Resume or Pause Uploads
In this Code Snippet it is the Server Side not Client on any Desktop Programm you must use byte ranges to calculate the uploaded bytes and missing of total bytes.
Here the PHP Code
<?php
$CHUNK = 8192;
try {
if (!($putData = fopen("php://input", "r")))
throw new Exception("Can't get PUT data.");
$tot_write = 0;
$tmpFileName = "/var/dev/tmp/PUT_FILE";
if (!is_file($tmpFileName)) {
fclose(fopen($tmpFileName, "x")); if (!($fp = fopen($tmpFileName, "w")))
throw new Exception("Can't write to tmp file");
while ($data = fread($putData, $CHUNK)) {
$chunk_read = strlen($data);
if (($block_write = fwrite($fp, $data)) != $chunk_read)
throw new Exception("Can't write more to tmp file");
$tot_write += $block_write;
}
if (!fclose($fp))
throw new Exception("Can't close tmp file");
unset($putData);
} else {
if (!($fp = fopen($tmpFileName, "a")))
throw new Exception("Can't write to tmp file");
while ($data = fread($putData, $CHUNK)) {
$chunk_read = strlen($data);
if (($block_write = fwrite($fp, $data)) != $chunk_read)
throw new Exception("Can't write more to tmp file");
$tot_write += $block_write;
}
if (!fclose($fp))
throw new Exception("Can't close tmp file");
unset($putData);
}
if ($tot_write != $file_size)
throw new Exception("Wrong file size");
$md5_arr = explode(' ', exec("md5sum $tmpFileName"));
$md5 = $md5sum_arr[0];
if ($md5 != $md5sum)
throw new Exception("Wrong md5");
} catch (Exception $e) {
echo '', $e->getMessage(), "\n";
}
?>
Oscar Fernandez Sierra ¶4 years ago
This is what worked for me. There are many examples in the web that don't work. I found in https://lornajane.net/posts/2009/putting-data-fields-with-php-curl.
IMPORTANT: You should not use the code
curl_setopt($ch, CURLOPT_PUT, true);
even if it seems to be the right option (it would be the right option for a POST request, with CURLOPT_POST, but it does not work for a PUT request).
Notice that the constant CURLOPT_CUSTOMREQUEST is used instead of CURLOPT_PUT, and that the value used is "PUT" instead of true.
<?php
$url = "....."; $data = array("a" => $a);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
$response = curl_exec($ch);
if ( ! $response) {
return false;
}
San ¶12 years ago
Instead of using fread fwrite to save uploaded content to a file.
stream_copy_to_stream is much cleaner.
polygon dot co dot in at gmail dot com ¶3 years ago
I was confused with file uploads using the PUT method.
My concern was why can't we upload multiple files using the PUT method with streams
PUT data comes in on the stdin stream
$putdata = fopen("php://input", "r");
Note the $putdata is a file pointer to the file content that is being uploaded.
The data is received on the server on the fly (which means available as it is received)
Secondly, when we are using parse_str(file_get_contents("php://input")).
This means the data is completely received on the server end and is then made available to the script.
When using fopen() one cant parse the data. This can be used when uploading a large file.
The file may range from 100's of MBs to Gigs where streams plays a major role.
Streams make the file data available to script in chunks instead of first saving in the temp folder.
Hence, when using $putdata = fopen("php://input", "r"); one can't pass the payload as well.
If someone wants to pass the payload the only option is in the URL query string.
willy at kochkonsult dot no ¶4 years ago
All the example code I found for using PUT with PHP always used a default hard-coded file extension for the incoming stream.
The filename from the incoming file PUT request can't be found anywhere from the incoming request (at least I couldn't find it) but mimetype can be found in the $_SERVER global variable.
I used this code to get the correct file extension:
$mimeType = $_SERVER['HTTP_CONTENT_TYPE'];
if ($mimeType!='application/pdf')
{
header('HTTP/1.1 405 Only PDF files allowed');
echo("Only PDF files are allowed for upload - this file is ".$mimeType);
die();
}
else $fileExtension = 'pdf';
If you have an Apache Tika server available, that would be the best option to analyze the file content to get the mimetype, but that might not be in scope for everyone :-)