Это то, что меня раздражало какое-то время. Я создаю RESTful API, который иногда должен получать файлы.
При использовании HTTP POST
мы можем читать data from $_POST
и files from $_FILES
.
При использовании HTTP GET
мы можем читать data from $_GET
и files from $_FILES
.
Однако при использовании HTTP PUT
AFAIK единственным способом чтения данных является использование php://input stream
.
Все хорошо и хорошо, пока я не хочу отправить файл через HTTP PUT. Теперь поток ввода php://работает не так, как ожидалось, поскольку он также имеет файл.
Вот как я сейчас читаю данные по запросу PUT:
(который отлично работает до тех пор, пока файлы не отправлены)
$handle = fopen('php://input', 'r');
$rawData = '';
while ($chunk = fread($handle, 1024)) {
$rawData .= $chunk;
}
parse_str($rawData, $data);
Когда я вывожу rawData, он показывает
-----ZENDHTTPCLIENT-44cf242ea3173cfa0b97f80c68608c4c
Content-Disposition: form-data; name="image_01"; filename="lorem-ipsum.png"
Content-Type: image/png; charset=binary
�PNG
���...etc etc...
���,
-----ZENDHTTPCLIENT-8e4c65a6678d3ef287a07eb1da6a5380
Content-Disposition: form-data; name="testkey"
testvalue
-----ZENDHTTPCLIENT-8e4c65a6678d3ef287a07eb1da6a5380
Content-Disposition: form-data; name="otherkey"
othervalue
Кто-нибудь знает, как правильно получать файлы через HTTP PUT или как разбирать файлы из потока ввода php://?
===== UPDATE # 1 =====
Я пробовал только этот метод, на самом деле не знаю, что я могу сделать иначе.
У меня нет ошибок с использованием этого метода, кроме того, что я не получаю желаемого результата опубликованных данных и файлов.
===== UPDATE # 2 =====
Я отправляю этот тестовый запрос, используя Zend_Http_Client, следующим образом: (до сих пор не было проблем с Zend_Http_Client)
$client = new Zend_Http_Client();
$client->setConfig(array(
'strict' => false,
'maxredirects' => 0,
'timeout' => 30)
);
$client->setUri( 'http://...' );
$client->setMethod(Zend_Http_Client::PUT);
$client->setFileUpload( dirname(__FILE__) . '/files/lorem-ipsum.png', 'image_01');
$client->setParameterPost(array('testkey' => 'testvalue', 'otherkey' => 'othervalue');
$client->setHeaders(array(
'api_key' => '...',
'identity' => '...',
'credential' => '...'
));
===== РЕШЕНИЕ =====
Оказывается, я сделал некоторые неправильные предположения, в основном, что HTTP PUT будет похож на HTTP POST. Как вы можете прочитать ниже, DaveRandom объяснил мне, что HTTP PUT не предназначен для передачи нескольких файлов по одному и тому же запросу.
Теперь я переместил передачу formdata из тела в строку запроса. Тело теперь содержит содержимое одного файла.
Для получения дополнительной информации прочитайте ответ DaveRandom. Это эпос.