Прежде всего, первое правило 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']
thingy.
Если у вас было несколько файлов для загрузки, вы просто повторяете процесс с $ content bit, конечно, с разным 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 прекрасно справляется с двоичным файлом.