Как RAW POST огромный XML файл с curl - PHP

есть ли способ сделать

curl -X POST -H "Content-Type:application/xml" --data @myfile.xml http://example.com

но непосредственно в PHP?

CURLOPT_PUT/CURLOPT_UPLOAD, а также file_get_contents, а также exec

не являются решениями, так как это должен быть POST, и файл огромен, поэтому он должен быть потоковым.

Любые идеи?

Ответ 1

У меня была аналогичная проблема, пытаясь подавать огромные файлы для приема в API-интерфейс elasticsearch с PHP, пока я не понял, что конечная точка API-интерфейса для массового использования принимала запросы PUT. В любом случае, этот код выполняет POST-запросы с огромными файлами:

$curl = curl_init();
curl_setopt( $curl, CURLOPT_PUT, 1 );
curl_setopt( $curl, CURLOPT_INFILESIZE, filesize($tmpFile) );
curl_setopt( $curl, CURLOPT_INFILE, ($in=fopen($tmpFile, 'r')) );
curl_setopt( $curl, CURLOPT_CUSTOMREQUEST, 'POST' );
curl_setopt( $curl, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json' ] );
curl_setopt( $curl, CURLOPT_URL, $url );
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, 1 );
$result = curl_exec($curl);
curl_close($curl);
fclose($in);

Здесь $tmpFile - это полный путь к файлу, содержащему тело запроса.

ПРИМЕЧАНИЕ. Важная часть - установка CURLOPT_CUSTOMREQUEST в 'POST', даже если установлен CURLOPT_PUT.

Вам нужно будет адаптировать заголовок Content-Type: к тому, что ожидает сервер.

Используя tcpdump, я могу подтвердить метод запроса POST:

POST /my_index/_bulk HTTP/1.1
Host: 127.0.0.1:9200
Accept: */*
Content-Type: application/json
Content-Length: 167401
Expect: 100-continue

[...snip...]

Я использую пакеты libcurl3 (версия 7.35.0-1ubuntu2.5) и php5-curl (версия 5.5.9 + dfsg-1ubuntu4.11) на Ubuntu 14.04.

Ответ 2

Curl поддерживает post, поэтому я считаю, что вы ищете что-то вроде этого: Проводка или загрузка файлов с помощью Curl With PHP

// URL on which we have to post data
$url = "http://localhost/tutorials/post_action.php";
// Any other field you might want to catch
$post_data['name'] = "khan";
// File you want to upload/post
$post_data['file'] = "@c:/logs.log";

// Initialize cURL
$ch = curl_init();
// Set URL on which you want to post the Form and/or data
curl_setopt($ch, CURLOPT_URL, $url);
// Data+Files to be posted
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
// Pass TRUE or 1 if you want to wait for and catch the response against the request made
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// For Debug mode; shows up any error encountered during the operation
curl_setopt($ch, CURLOPT_VERBOSE, 1);
// Execute the request
$response = curl_exec($ch);

// Just for debug: to see response
echo $response;

(Весь кредит для кода оригиналу связанного автора).

Что касается "огромного", вам нужно быть более конкретным - kb, mb, gb, tb? Дополнительные проблемы будут связаны с тем, как долго PHP script может оставаться в живых без использования автоматического завершения, script использования памяти (что может потребовать, чтобы вещи обрабатывались в кусках, а не для загрузки всего файла) и т.д.

EDIT: Ах, для сообщения RAW, я думаю, вам понадобится следующее: Необработанные POST с использованием Curl в PHP