【问题标题】:Array 2 string conversion while using CURLOPT_POSTFIELDS使用 CURLOPT_POSTFIELDS 时的数组 2 字符串转换
【发布时间】:2016-05-02 05:50:53
【问题描述】:

我有以下代码:

// $postfields = array();
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);

我的$postfields 变量是一个参数数组。我注意到有数组到字符串的转换。它确实有效。

我可以使用http_build_query() 函数来取消通知,但是我使用@path_to_file 来包含发布文件。和http_build_query() 中断文件包括。

我想知道是否有更多“正确”的方法可以做到这一点。不生成通知。

【问题讨论】:

    标签: php arrays curl libcurl notice


    【解决方案1】:

    $postfields 数组本身是否有一些值?这很可能是导致通知的原因。 curl_setops 期望它的第三个参数是一个键和值都是字符串的数组,正如PHP's manual page for the function 中所述,尽管可能不是很清楚:

    此参数可以作为 urlencoded 字符串(如 'para1=val1&para2=val2&...')或以字段名称作为键、字段数据作为值的数组形式传递。

    在这句话中,关键是 para1/2 和 val1/2 是字符串,如果需要,可以将它们作为数组提供,其中键是 para1 和 para2,值是 val1 和 val2。

    两种方法可以消除通知

    第一个是使用http_build_query(),并用CURLFile objects 替换您对@filepath 的使用。不幸的是,这只有在您使用 PHP 5.5 或更高版本时才有可能。手册页有一个非常清晰简单的example of use

    如果您不适合使用 CURLFiles,那么 第二个 方法是 json_encode() $postfields 数组的值,它们本身就是数组。这并不优雅,它需要您在另一端解码 JSON。

    【讨论】:

    • 确实,这个数组的 3 个值本身就是数组……我不使用它们,所以可能没有正确导出。没想到那些可能是内部数组。
    • http_build_queryCURLFiles 一起使用不起作用。 CURLFiles 将被转换为数组,并作为常规 $_POST 数据出现。
    【解决方案2】:

    如果要发送多维数组,j11e 的答案将不起作用

    试试这个递归函数。

    https://gist.github.com/yisraeldov/ec29d520062575c204be7ab71d3ecd2f

    <?php
    function build_post_fields( $data,$existingKeys='',&$returnArray=[]){
        if(($data instanceof CURLFile) or !(is_array($data) or is_object($data))){
            $returnArray[$existingKeys]=$data;
            return $returnArray;
        }
        else{
            foreach ($data as $key => $item) {
                build_post_fields($item,$existingKeys?$existingKeys."[$key]":$key,$returnArray);
            }
            return $returnArray;
        }
    }
    

    你可以这样使用它。

    curl_setopt($ch, CURLOPT_POSTFIELDS, build_post_fields($postfields));
    

    【讨论】:

    • 这正是我所需要的。为了在 curl 请求中使用 等,这是正确的答案。谢谢Yysrael
    【解决方案3】:

    使用 Laravel 对我有用的一件事是在请求标头中使用标签 'Content-Type: application/json',并发送我的数据 json 编码如下:

    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Accept: application/json'));
    curl_setopt($ch, CURLOPT_POST, 1); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
    

    在接收请求中的参数的函数中我不需要使用json解码函数,我就像访问参数一样

    $request-&gt;something

    【讨论】:

      【解决方案4】:

      经过一个小时的研究,这里是我修复代码的方式:

      $strVar = '';
      if ($data) {
              $ea = build_post_fields($data);
              foreach($ea as $key=>$val) {
                      $strVar.= "$key=$val&";
              }
      }
      
      
      /* eCurl */
      $curl = curl_init($url);
      
      /* Set Array data to POST */
      curl_setopt( $curl, CURLOPT_POSTFIELDS, ($strVar) );
      
      

      下面是我从@Yisrael Dov 那里得到的功能:

      
      function build_post_fields( $data, $existingKeys='', $returnArray=[]){
          if(($data instanceof CURLFile) or !(is_array($data) or is_object($data))){
              $returnArray[$existingKeys]=$data;
              return $returnArray;
          }
          else{
              foreach ($data as $key => $item) {
                  build_post_fields($item,$existingKeys?$existingKeys."[$key]":$key,$returnArray);
              }
              return $returnArray;
          }
      }
      

      效果很好!您可以发布一个深度数组,例如:

      $post_var = array(
      'people' => array('Lam', 'Hien', 'Nhi'),
      'age' => array(12, 22, 25)
      );
      

      美好的一天!

      【讨论】:

      • 欢迎来到 SO。感谢您的回答,但您应该感谢 Yisrael Dov 在 his own answer 中提供了函数 build_post_fields,之前已发布。请注意,您的函数会构建一个带有不必要的尾随 &amp; 的查询字符串。
      • 感谢您的留言,对不起,build_post_fields 属于 @yisrael-dov
      猜你喜欢
      • 2021-12-05
      • 2018-10-09
      • 2021-05-03
      • 2016-01-25
      • 2016-03-23
      • 2011-12-11
      • 1970-01-01
      • 2014-11-13
      • 2021-01-04
      相关资源
      最近更新 更多