Запись нескольких файлов в одном запросе CURL - PullRequest
5 голосов
/ 06 апреля 2011

Есть ли способ использовать PHP curl для отправки нескольких файлов в одном запросе?

Я понимаю, что вы можете отправить один файл, используя следующее:

$fh = fopen("files/" . $title . "/" . $name, "w");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, trim($url));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_FILE, $fh);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)");
curl_exec($ch);
echo curl_error($ch);
curl_close($ch);

Но я хочу иметь возможность писать, скажем, 3 файла, используя один запрос.

Возможно, есть способ записать байты в запрос до curl_exec()?

Ответы [ 3 ]

8 голосов
/ 06 апреля 2011

Полный пример будет выглядеть примерно так:

<?php
$xml = "some random data";
$post = array(
     "uploadData"=>"@/Users/whowho/test.txt", 
     "randomData"=>$xml, 
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, trim("http://someURL/someTHing"));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)");
curl_exec($ch);
echo curl_error($ch);
curl_close($ch);


?>
5 голосов
/ 06 апреля 2011

Вы можете использовать это

$post = array(
     "file1"=>"@/path/to/myfile1.jpg",
     "file2"=>"@/path/to/myfile2.jpg",
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post); 
1 голос
/ 04 мая 2018

Я искал способ отправить запрос на публикацию с несколькими файлами, используя curl. Но все примеры кода делали не так, как браузер. Глобал $ _ FILES не содержит обычного массива, описанного в PHP.

Теперь я выяснил, почему: смещения, где отсутствует [i]

см. http://php.net/manual/de/class.curlfile.php#121971

Без «трюка» вы получите другой результат в $ _ FILES

[
    'foo_bar' => [
        'name'     => 'path/to/my_file_1.png',
        'type'     => 'application/octet-stream',
        'tmp_name' => '/tmp/phpim24ij',
        'error'    => 0,
        'size'     => 123,
    ],
]

или

[
    'foo_bar_1' => [
        'name'     => 'path/to/my_file_1.png',
        'type'     => 'application/octet-stream',
        'tmp_name' => '/tmp/phpim24ij',
        'error'    => 0,
        'size'     => 123,
    ],
    'foo_bar_2' => [
        'name'     => 'path/to/my_file_1.png',
        'type'     => 'application/octet-stream',
        'tmp_name' => '/tmp/phpim24ij',
        'error'    => 0,
        'size'     => 123,
    ],
]

Но это не то, что мы хотим.

То, что мы хотим - это обычный $ _ FILES массив, подобный

[
    'foo_bar' => [
        'name'     => [
            0 => 'path/to/my_file_1.png',
            1 => 'path/to/my_file_2.png',
        ],
        'type'     => [
            0 => 'application/octet-stream',
            1 => 'application/octet-stream',
        ],
        'tmp_name' => [
            0 => '/tmp/phpSPAjHW',
            1 => '/tmp/php0fOmK4',
        ],
        'error'    => [
            0 => 0,
            1 => 0,
        ],
        'size'     => [
            0 => 123,
            1 => 234,
        ],
    ],
]

Вот код:

* +1032 * Пример: * 1 033 *
$url = "http://api-foo.com/bar/baz";
$uploadFormInputFieldName = 'foo_bar';
$files = [
    'path/to/my_file_1.png',
    'path/to/my_file_2.png',
    // ...
];

$postData = [];
$i = 0;
foreach ($files as $file) {
    if (function_exists('curl_file_create')) {
        $file = curl_file_create($file);
    } else {
        $file = '@' . realpath($file);
    }
    // here is the thing: post data needs to be $posData["foo_bar[0]"], $posData["foo_bar[1]"], ...
    $postData["{$uploadFormInputFieldName}[{$i}]"] = $file;
    $i++;
}

$httpClient = $this->getHttpClient($url); // get your client
$httpClient->setHeader('Content-Type', 'multipart/form-data');
$response = $httpClient->post($postData); // send post request
...