【问题标题】:Translating "data-binary" from cURL to PHP将“数据二进制”从 cURL 转换为 PHP
【发布时间】:2017-02-21 03:28:00
【问题描述】:

我需要在 PHP 中重新创建它:

curl -X POST --user <username>:<password>
--header "Content-Type: text/plain;charset=utf-8"
--header "Accept: application/json"
--data-binary @<filename>
"https://gateway.watsonplatform.net/personality-insights/api/v3/profile"

我有这个:

$request_headers = array();
$request_headers[] = 'Content-Type: text/plain;charset=utf-8';
$request_headers[] = 'Content-Language: en';
$request_headers[] = 'Accept-Language: en';

$simple_data = 'washingtonpost by the intelligence community';
    curl_setopt_array( $ch2, array(
        CURLOPT_POST => 1,
        CURLOPT_POSTFIELDS => $simple_data,
        CURLOPT_HEADER => $request_headers,
        CURLOPT_USERPWD => 'XXXX:YYYY',
    )
    );
    $response2 = curl_exec( $ch2 );

我的代码没有考虑到 --data-binary 部分,但我不确定如何将其“翻译”成 PHP。另外,我可以使用纯文本(API 接受)的数据二进制而不是 JSON 吗?

【问题讨论】:

  • 在您的代码中,CURLOPT_HEADER 应该是 CURLOPT_HTTPHEADER 以设置请求标头。否则,POSTFIELDS 与自定义 Content-Type 一样正确。
  • @drew010 这正是问题所在!谢谢!如果您提交作为答案,我可以接受。欣赏它。

标签: php curl ibm-watson


【解决方案1】:

您所拥有的已经是 --data-binary 等价物。见CURLOPT_POSTFIELDS API docs

您必须确保按照您希望服务器接收数据的方式格式化数据。 libcurl 不会以任何方式为您转换或编码它。

docs for the command-line --data-binary option比较:

这完全按照指定的方式发布数据,没有任何额外的处理。

至于你问题的第二部分:

我可以使用纯文本的二进制数据(API 接受)而不是 JSON

是的,来自命令行的--data-binary 和来自API 的CURLOPT_POSTFIELDS

【讨论】:

  • 谢谢...这给了我415 Unsupported Media Type 错误,鉴于我在此示例中尝试发送的非常简单的字符串,我无法追踪这些错误。
  • 我认为415 Unsupported Media Type 只是查看Content-Type: text/plain 标头并说它不支持的服务(尽管为什么我不知道,因为你的问题表明它应该支持)。我想将其更改为application/json 并再次尝试将是要做的事情(如果你还没有这样做的话)。但无论如何,据我所知,415 并不是由您的 libcurl 代码发送的任何格式错误引起的。
  • 我正在使用 CLI 运行完全相同的东西,它工作得非常好。我缺少的翻译中是否有一些正在更改(或未更改)的内容?
  • 我认为问题正是在stackoverflow.com/questions/42358104/… 上面的评论中提到的,也就是说,你需要CURLOPT_HTTPHEADER 而不是CURLOPT_HEADER
【解决方案2】:

如果您将CURLOPT_POSTFIELDS 的值设置为一个数组(如果您使用CURLFile,它是),帖子将被格式化为多部分,打破data-binary 部分。

我没有找到在没有multipart/form-data 副作用的情况下使用 CURLFile 的方法...

我使用的是这个,但它使用了file_get_contents,这对内存不是很友好(它会将整个文件加载到内存中):

    <?php

    $file_local_full = '/tmp/foobar.png';

    $headers = array(
        "Content-Type: application/octet-stream", // or whatever you want
    );

    // if the file is too big, it should be streamed
    $curl_opts = array(
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_CUSTOMREQUEST => "POST",
        CURLOPT_HTTPHEADER => $headers,
        CURLOPT_POSTFIELDS => file_get_contents($file_local_full),
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1
    );
    // echo "curl_opts:\n" . print_r($curl_opts, true) . "\n"; exit;

    $curl = curl_init();
    curl_setopt_array($curl, $curl_opts);

    $response = curl_exec($curl);

【讨论】:

    【解决方案3】:

    好的,我找到了一种不用multipart/form-data的方式来流式上传,关键是欺骗curl,我们先告诉他PUT,然后是POST:

        <?php
        
        $file_local_full = '/tmp/foobar.png';
        $content_type = mime_content_type($file_local_full);
    
        $headers = array(
            "Content-Type: $content_type", // or whatever you want
        );
    
        $filesize = filesize($file_local_full);
        $stream = fopen($file_local_full, 'r');
    
        $curl_opts = array(
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_PUT => true,
            CURLOPT_CUSTOMREQUEST => "POST",
            CURLOPT_HTTPHEADER => $headers,
            CURLOPT_INFILE => $stream,
            CURLOPT_INFILESIZE => $filesize,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1
        );
    
        $curl = curl_init();
        curl_setopt_array($curl, $curl_opts);
    
        $response = curl_exec($curl);
    
        fclose($stream);
    
        if (curl_errno($curl)) {
            $error_msg = curl_error($curl);
            throw new \Exception($error_msg);
        }
    
        curl_close($curl);
    

    学分:How to POST a large amount of data within PHP curl without memory overhead?

    【讨论】:

      猜你喜欢
      • 2013-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多