【问题标题】:php curl multipart/form-data : file content not postedphp curl multipart/form-data:文件内容未发布
【发布时间】:2018-05-01 07:36:14
【问题描述】:

本网站上关于此主题的许多答案,但没有一个对我有帮助。

我正在尝试将文件发布到盒子(云存储)。应该很容易,但事实并非如此。

我使用RequestBin进行调试。

在命令行上使用 curl 时,效果很好(文件发布到 Box):

curl https://requestb.in/1bw1 -H "Authorization: Bearer supersecret" -H "Content-Type: multipart/form-data" -X POST -F file=@/tmp/testfile.pdf

当尝试使用 php curl 执行相同操作(将文件上传到 Box)时,它会失败(根本没有响应,这意味着找不到文件内容)。

我还在 RequestBin 上看到我的 POST 看起来不同。

Curl cli(正确):

原始的身体

------------------cd86e864290b 内容处置:表单数据;名称="属性"

{"name":"testfile.pdf", "parent":{"id":"40801665641"}} ------------------------------cd86e864290b 内容处置:表单数据;名称=“文件”;文件名="testfile.pdf" 内容类型:application/octet-stream

RIFFäÊWAVEfmt ...

Curl php(不正确):

原始的身体

------------------7ab3fffab8c6 内容处置:表单数据;名称="属性"

{"name":"testfile.pdf","parent":{"id":"42035106321"}} ------------------------------7ab3fffab8c6 内容处置:表单数据;名称="文件"

@../faxout/testfile.pdf ------------------7ab3fffab8c6--

这显然不一样,我不知道如何获得相同的结果。

我的 PHP 代码:

$dataFile = array(
        'name' => $faxfilename,
        'parent' => array(
                'id' => $subfolderID,
            )
        );
    $PostData= array(
        'attributes' => json_encode($dataFile),
        'file' => "@$target"
    );
    $headers3=array(
        "Authorization: Bearer supersecret",
        "Content-Type: multipart/form-data"
        );

    //$filesurl = "https://upload.box.com/api/2.0/files/content";
    $filesurl = 'https://requestb.in/1bw1';
    $curlFILE = curl_init();
    curl_setopt_array($curlFILE, array(
        CURLOPT_URL => $filesurl,
        CURLOPT_HTTPHEADER => $headers3,
        CURLOPT_POST => TRUE,
        CURLOPT_POSTFIELDS => $PostData,
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_SSL_VERIFYPEER => FALSE,
        CURLOPT_SSL_VERIFYHOST => FALSE
    ));

我试过了:

CURLOPT_POSTFIELDS => http_build_query($PostData),

我试过了:

'@'.realpath($target)

我似乎没有得到我想要发布的文件的正确格式。

【问题讨论】:

    标签: php pdf curl


    【解决方案1】:

    您正在寻找CURLFile

    $curlFILE = curl_init ();
    curl_setopt_array ( $curlFILE, array (
            CURLOPT_URL => 'https://requestb.in/1bw1',
            CURLOPT_HTTPHEADER => array (
                    "Authorization: Bearer supersecret" 
            ),
            CURLOPT_POST => TRUE,
            CURLOPT_POSTFIELDS => array (
                    'file' => new CURLFile ( '/tmp/testfile.pdf' ) 
            ),
            //CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_SSL_VERIFYPEER => FALSE,
            CURLOPT_SSL_VERIFYHOST => FALSE 
    ) );
    curl_exec($curlFILE);
    

    另外,当使用 multipart/form-data 或 application/x-www-urlencoded 编码时,不要手动设置 content-type 标头,curl 会自动为您设置合适的标头,而且与您不同,curl 不会这样做时不要打错字。

    此外,如果设置选项时出现问题,curl_setopt_array 将返回 bool(false),并且您不应忽略这些错误,因此我建议改用此函数,它将任何 curl setopt 错误转换为 RuntimeException

    function ecurl_setopt_array($ch, array $options) {
        if (! curl_setopt_array ( $ch, $options )) {
            throw new \RuntimeException ( 'curl_setopt_array failed. ' . curl_errno ( $ch ) . ': ' . curl_error ( $ch ) );
        }
    }
    

    还有一个提示,在调试 curl 代码时,启用 CURLOPT_VERBOSE。

    【讨论】:

    • 谢谢。我知道 CURLFile() 对象。我唯一的问题是我有 php 版本 5.4.36。所以这对我来说是没有选择的。
    • @user2795648 你的 php 版本太旧,不安全,不再收到重要的安全更新(也没有错误修复,也没有任何类型的更新),帮自己一个忙,升级到 5.6。也就是说,这样做的 5.4 版本是 CURLOPT_POSTFIELDS => array ( 'file' => '@/tmp/testfile.pdf' ) - 但这不适用于 5.5+(没有 CURLOPT_SAFE_UPLOAD ),并且不适用于 php 7.0+ 期间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-03
    • 2018-02-24
    • 1970-01-01
    • 2015-09-19
    相关资源
    最近更新 更多