简体   繁体   English

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

[英]How do I upload a file to an AWS Presigned URL with PHP Curl?

I'm trying to upload a file from a '<form enctype="multipart/form-data"><input type="file">...' to AWS via a presigned URL using PHP Curl.我正在尝试使用 PHP Z66B29B9F2BDC949A7545904 通过预签名的 URL 将文件从 '<form enctype="multipart/form-data"><input type="file">...' 上传到 AWS

While the file appears to be uploaded successfully, after I download the recently uploaded file, trying to open the newly downloaded file fails.虽然文件似乎已成功上传,但在我下载最近上传的文件后,尝试打开新下载的文件失败。 I get either "this file is corrupted" or "it looks like we don't support this file format" or "we cant open this file" depending on the file type.我收到“此文件已损坏”或“我们似乎不支持此文件格式”或“我们无法打开此文件”,具体取决于文件类型。 I'm getting no response from AWS via curl_exec or curl_error on the upload.我在上传时没有通过 curl_exec 或 curl_error 从 AWS 得到任何响应。

I basically copied the PHP code from POSTMAN since POSTMAN uploads the file successfully when the file is attached as "binary".我基本上从 POSTMAN 复制了 PHP 代码,因为 POSTMAN 在文件附加为“二进制”时成功上传文件。 Since my code attaches the file via CURLOPT_POSTFIELDS in my code, could this be a problem?由于我的代码在我的代码中通过 CURLOPT_POSTFIELDS 附加了文件,这可能是个问题吗? Every other example I've seen attaches the file via curl_file_create and CURLOPT_POSTFIELDS, so that's what I'm using.我见过的所有其他示例都通过 curl_file_create 和 CURLOPT_POSTFIELDS 附加文件,所以这就是我正在使用的。

The only instructions I have in uploading the file is:我上传文件的唯一说明是:

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

I've tried to change the content-type in the header to the actual uploaded file type, but neither works.我尝试将 header 中的内容类型更改为实际上传的文件类型,但都不起作用。 I've tried both CURLFile and curl_file_create.我已经尝试过 CURLFile 和 curl_file_create。 The files after uploading to my test server and my website server are all still valid prior to upload to AWS.上传到我的测试服务器和我的网站服务器后的文件在上传到 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);

I'm looking for the file to be uploaded successfully to AWS via a presigned URL, downloaded successfully, and opened successfully.我正在寻找要通过预签名的 URL 成功上传到 AWS 的文件,下载成功,并成功打开。

[UPDATE] [更新]

Attempted to upload text files instead of images and pdfs, which were the main file types we were developing for.尝试上传文本文件而不是图像和 pdf,这是我们开发的主要文件类型。 Downloading those files ended up being "successful" in that I was able to open them up, however, there was text added to the beginning of the text file.下载这些文件最终是“成功的”,因为我能够打开它们,但是,文本文件的开头添加了文本。

If uploaded as Content-Type:multipart/form-data, the file was still downloadable, but when opened it, this text was added to the beginning of the file.如果作为 Content-Type:multipart/form-data 上传,该文件仍然可以下载,但打开它时,此文本会添加到文件的开头。

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

If uploaded as Content-Type: $content_type, the download link opened the file in a new browser window with this text added to the file.如果作为 Content-Type: $content_type 上传,下载链接会在新浏览器 window 中打开文件,并将此文本添加到文件中。

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

Replacing $payload = array('upload-file' => $cFile);替换$payload = array('upload-file' => $cFile); with $payload = file_get_contents( $tmp_name );$payload = file_get_contents( $tmp_name ); solved my issue.解决了我的问题。 Looks like I don't need curl_file_create or the array and key upload-file at all.看起来我根本不需要curl_file_create或数组和密钥upload-file

Also, https://stackoverflow.com/a/21888136 metioned loading the content directly should remove the header information, and it did.此外, https://stackoverflow.com/a/21888136 提到直接加载内容应该删除 header 信息,它确实做到了。

Thanks all for insight, as you did point me in the right direction!感谢所有人的洞察力,因为您确实为我指明了正确的方向!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM