在一个请求中使用 CurlFile 发送多维数据和多个文件

假设我们有一个类似下面的表格。我们希望通过 AJAX 将数据发送到我们的 Web 服务器,并从那里发送到外部服务器上运行的脚本。

StackOverflow 文档

所以我们有正常的输入,一个多选字段和一个文件 dropzone,我们可以上传多个文件。

假设 AJAX POST 请求成功,我们在 PHP 站点上获得以下数据:

// print_r($_POST)

Array
(
    [first_name] => John
    [last_name] => Doe
    [activities] => Array
        (
            [0] => soccer
            [1] => hiking
        )
)

并且文件应该如下所示

// print_r($_FILES)

Array
(
    [upload] => Array
        (
            [name] => Array
                (
                    [0] => my_photo.jpg
                    [1] => my_life.pdf
                )

            [type] => Array
                (
                    [0] => image/jpg
                    [1] => application/pdf
                )

            [tmp_name] => Array
                (
                    [0] => /tmp/phpW5spji
                    [1] => /tmp/phpWgnUeY
                )

            [error] => Array
                (
                    [0] => 0
                    [1] => 0
                )

            [size] => Array
                (
                    [0] => 647548
                    [1] => 643223
                )

        )

)

到现在为止还挺好。现在我们要使用带有 CurlFile 类的 cURL 将此数据和文件发送到外部服务器

由于 cURL 只接受一个简单但不是多维的数组,我们必须首先展平$ _POST 数组。

为此,你可以使用此功能,例如 ,它提供以下内容:

// print_r($new_post_array)

Array
(
    [first_name] => John
    [last_name] => Doe
    [activities[0]] => soccer
    [activities[1]] => hiking
)

下一步是为上传的文件创建 CurlFile 对象。这是通过以下循环完成的:

$files = array();

foreach ($_FILES["upload"]["error"] as $key => $error) {
    if ($error == UPLOAD_ERR_OK) {

        $files["upload[$key]"] = curl_file_create(
            $_FILES['upload']['tmp_name'][$key],
            $_FILES['upload']['type'][$key],
            $_FILES['upload']['name'][$key]
        );
    }
}

curl_file_create 是 CurlFile 类的辅助函数,它创建了 CurlFile 对象。我们使用名为“upload [0]”和“upload [1]”的键保存$ files 数组中的每个对象。

我们现在必须将 flattened post 数组和 files 数组合并并将其保存为$ data,如下所示:

$data = $new_post_array + $files;

最后一步是发送 cURL 请求:

$ch = curl_init();

curl_setopt_array($ch, array(
    CURLOPT_POST => 1,
    CURLOPT_URL => "https://api.externalserver.com/upload.php",
    CURLOPT_RETURNTRANSFER => 1,
    CURLINFO_HEADER_OUT => 1,
    CURLOPT_POSTFIELDS => $data
));

$result = curl_exec($ch);

curl_close ($ch);

由于$ data 现在是一个简单(平面)数组,因此 cURL 会自动发送带有内容类型的 POST 请求:multipart / form-data

在外部服务器上的 upload.php 中,你现在可以像往常一样使用$ _POST 和$ _FILES 获取发布数据和文件。