web-dev-qa-db-fra.com

Téléchargez un fichier à l'aide de file_get_contents

Je me rends compte que je peux le faire très facilement avec CURL, mais je me demandais s'il était possible d'utiliser file_get_contents() avec le contexte de flux http pour télécharger un fichier sur un serveur Web distant, et si oui, comment?

37
Shabbyrobe

Tout d'abord, la première règle de multipart Content-Type est de définir une limite qui sera utilisé comme délimiteur entre chaque partie (car comme son nom l'indique, il peut avoir plusieurs les pièces). La limite peut être toute chaîne qui n'est pas contenue dans le corps du contenu . J'utilise généralement un horodatage:

define('MULTIPART_BOUNDARY', '--------------------------'.microtime(true));

Une fois votre limite définie, vous devez l'envoyer avec le Content-Type en-tête pour indiquer au serveur Web le délimiteur à attendre:

$header = 'Content-Type: multipart/form-data; boundary='.MULTIPART_BOUNDARY;

Une fois cela fait, vous devez créer un corps de contenu approprié qui correspond à la spécification HTTP et à l'en-tête que vous avez envoyé. Comme vous le savez, lorsque vous POSTEZ un fichier à partir d'un formulaire, vous aurez généralement un nom de champ de formulaire. Nous allons le définir:

// equivalent to <input type="file" name="uploaded_file"/>
define('FORM_FIELD', 'uploaded_file'); 

Ensuite, nous construisons le corps du contenu:

$filename = "/path/to/uploaded/file.Zip";
$file_contents = file_get_contents($filename);    

$content =  "--".MULTIPART_BOUNDARY."\r\n".
            "Content-Disposition: form-data; name=\"".FORM_FIELD."\"; filename=\"".basename($filename)."\"\r\n".
            "Content-Type: application/Zip\r\n\r\n".
            $file_contents."\r\n";

// add some POST fields to the request too: $_POST['foo'] = 'bar'
$content .= "--".MULTIPART_BOUNDARY."\r\n".
            "Content-Disposition: form-data; name=\"foo\"\r\n\r\n".
            "bar\r\n";

// signal end of request (note the trailing "--")
$content .= "--".MULTIPART_BOUNDARY."--\r\n";

Comme vous pouvez le voir, nous envoyons le Content-Disposition en-tête avec le form-data disposition, ainsi que le paramètre name (le nom du champ du formulaire) et le paramètre filename (le nom de fichier d'origine). Il est également important d'envoyer le Content-Type en-tête avec le type MIME approprié, si vous souhaitez remplir correctement le $_FILES[]['type'] bidule.

Si vous aviez plusieurs fichiers à télécharger, vous répétez simplement le processus avec le bit $ content , avec bien sûr, un FORM_FIELD pour chaque fichier.

Maintenant, construisez le contexte:

$context = stream_context_create(array(
    'http' => array(
          'method' => 'POST',
          'header' => $header,
          'content' => $content,
    )
));

Et exécutez:

file_get_contents('http://url/to/upload/handler', false, $context);

REMARQUE: Il n'est pas nécessaire de coder votre fichier binaire avant de l'envoyer. HTTP peut très bien gérer le binaire.

84
netcoder