Загрузите файл с помощью file_get_contents

Я понимаю, что могу сделать это с CURL очень легко, но мне было интересно, можно ли использовать file_get_contents() с контекстом HTTP-потока для загрузки файла на удаленный веб-сервер, и если да, то каким образом?

Прежде всего, первое правило multipart Content-Type заключается в определении границы, которая будет использоваться в качестве разделителя между каждой частью (поскольку, как сказано в названии, она может иметь несколько частей). Границей может быть любая строка, которая не содержится в теле содержимого . Обычно я использую временную метку:

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

Как только ваша граница определена, вы должны отправить ее с заголовком Content-Type чтобы сообщить веб-серверу, что ожидать от разделителя:

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

Как только это будет сделано, вы должны создать правильное тело контента, которое соответствует спецификации HTTP и отправленному вами заголовку. Как вы знаете, при отправке файла из формы у вас обычно будет имя поля формы. Мы определим это:

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

Затем мы создаем тело контента:

 $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"; 

Как вы можете видеть, мы отправляем заголовок Content-Disposition с расположением form-data вместе с параметром name (имя поля формы) и параметром filename (исходное имя файла). Также важно отправить заголовок Content-Type с соответствующим типом MIME, если вы хотите правильно заполнить $_FILES[]['type'] .

Если у вас было несколько файлов для загрузки, вы просто повторяете процесс с битом $ content , с, разумеется, другим FORM_FIELD для каждого файла.

Теперь создайте контекст:

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

И выполните:

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

ПРИМЕЧАНИЕ. Нет необходимости кодировать ваш двоичный файл перед его отправкой. HTTP может обрабатывать двоичные файлы просто отлично.

Вы можете выдать запрос POST с заголовком Content-Type: multipart/form-data и вручную закодировать свой файл в виде multipart/form-data .

 file_get_contents(URL, false, stream_context_create(array( 'http' => array( 'method' => 'POST', 'headers' => 'Content-Type: multipart/form-data' 'content' => MULTIPART_ENCODED_FILE, ), )));