如何使用PHP Curl将文件上传到AWS Presigned URL?

时间:2019-10-30 20:16:57

标签: php amazon-web-services curl postman

我正在尝试使用PHP Curl通过预签名URL从'

...'上传文件到AWS。

虽然文件似乎已成功上传,但我下载了最近上传的文件后,尝试打开新下载的文件失败。我收到“此文件已损坏”或“看起来我们不支持此文件格式”或“我们无法打开此文件”的信息,具体取决于文件类型。我在上传时没有通过curl_exec或curl_error收到来自AWS的响应。

我基本上是从POSTMAN复制PHP代码的,因为当文件附加为“二进制”文件时POSTMAN成功上传了文件。由于我的代码通过CURLOPT_POSTFIELDS在我的代码中附加了文件,因此这可能是个问题吗?我见过的每一个其他示例都通过curl_file_create和CURLOPT_POSTFIELDS附加文件,所以这就是我所使用的。

我上传文件的唯一说明是:

curl -X PUT \
  "https://PRESIGNED_PUT_URL_FROM_RESPONSE" \
  --upload-file ~/Documents/Files/the_file.pdf

我尝试将标头中的内容类型更改为实际上传的文件类型,但均无效。我已经尝试了CURLFile和curl_file_create。上传到我的测试服务器和网站服务器之后的文件在上传到AWS之前都仍然有效。

    $file_name = $post_files[$FILES_file]["name"];
    $content_type = $post_files[$FILES_file]["type"];
    $TheFileSize = $post_files[$FILES_file]["size"];
    $tmp_name = $post_files[$FILES_file]["tmp_name"];
    $curl = curl_init();
    $cFile = curl_file_create($tmp_name, $content_type, $file_name);

    $payload = array('upload-file' => $cFile);

    $curlOptions = array(
            CURLOPT_URL            => $TheAWSPresignedURL,
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_CUSTOMREQUEST  => "PUT",
            CURLOPT_ENCODING       => "",
            CURLOPT_POST           => 1,
            CURLOPT_MAXREDIRS      => 10,
            CURLOPT_TIMEOUT        => 300,
            CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_1_1,
            CURLOPT_INFILESIZE     => $TheFileSize,
            CURLOPT_HTTPHEADER     => array(
                "Accept: */*",
                "Accept-Encoding: gzip, deflate",
                "Cache-Control: no-cache",
                "Connection: keep-alive",
                "Content-Length: ".$TheFileSize,
                "Content-Type: multipart/form-data",
                "Host: s3.amazonaws.com"
            ),
        );
    curl_setopt_array($curl, $curlOptions);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $payload);  
    $response = curl_exec($curl);

我正在寻找要通过预签名URL成功上传到AWS,成功下载并成功打开文件的文件。

[更新]

尝试上传文本文件,而不是图像和pdf,这是我们正在开发的主要文件类型。下载这些文件最终是“成功”的,因为我能够打开它们,但是,在文本文件的开头添加了文本。

如果以Content-Type:multipart / form-data的形式上传,则该文件仍可下载,但是在打开时,此文本已添加到文件的开头。

--------------------------9cd644e15677104b Content-Disposition: form-data; name="upload-file"; filename="SimpleTextFile.txt" Content-Type: text/plain

如果以Content-Type:$ content_type的形式上传,则下载链接会在新的浏览器窗口中打开该文件,并将此文本添加到文件中。

--------------------------3dca3db029b41ae2 Content-Disposition: attachment; name="upload-file"; filename="SimpleTextFile2.txt" Content-Type: text/plain

1 个答案:

答案 0 :(得分:0)

$payload = array('upload-file' => $cFile);代替$payload = file_get_contents( $tmp_name );解决了我的问题。看起来我根本不需要curl_file_create或数组和键upload-file

此外,https://stackoverflow.com/a/21888136建议直接加载内容应删除标头信息,并且确实如此。

感谢您的洞察力,因为您确实指出了我正确的方向!