Posting multidimensional array with PHP and CURL

前端 未结 8 1954
难免孤独
难免孤独 2020-11-27 06:29

I\'m having trouble posting form data via CURL to a receiving PHP script located on a different host.

I get an Array to string conversion error

相关标签:
8条回答
  • 2020-11-27 06:29

    First I would like to thank Daniel Vandersluis for his insightful reply. Based on his input I came up with this to fix the problem from the original question:

    <?php
    
    function curl_postfields_flatten($data, $prefix = '') {
      if (!is_array($data)) {
        return $data; // in case someone sends an url-encoded string by mistake
      }
    
      $output = array();
      foreach($data as $key => $value) {
        $final_key = $prefix ? "{$prefix}[{$key}]" : $key;
        if (is_array($value)) {
          // @todo: handle name collision here if needed
          $output += curl_postfields_flatten($value, $final_key);
        }
        else {
          $output[$final_key] = $value;
        }
      }
      return $output;
    }
    

    Usage should look like this:

    curl_setopt($this->ch, CURLOPT_POSTFIELDS, curl_postfields_flatten($post));
    

    This function will convert arrays like this:

    array(
      'a' => 'a',
      'b' => array(
        'c' => array(
          'd' => 'd',
          'e' => array(
            'f' => 'f',
          ),
        ),
      ),
    );
    

    Into this:

    array(
      'a' => 'a',
      'b[c][d]' => 'd',
      'b[c][e][f]' => 'f',
    )
    

    It doesn't handle cases with mixed format when there is a key collision like this:

    array(
     'b[c]' => '1',
     'b' => array(
       'c' => '2', 
      ),
    );
    

    The output will contain only the first value for that key

    array(
     'b[c]' => '1'
    )
    
    0 讨论(0)
  • 2020-11-27 06:30

    You'd have to build the POST string manually, rather than passing the entire array in. You can then override curl's auto-chose content header with:

    curl_setopt($c, CURLOPT_HTTPHEADER, array("Content-type: multipart/form-data"));
    

    Serializing/json-ifying would be easier, but as you say, you have no control over the receiving end, so you've got a bit of extra work to do.

    0 讨论(0)
  • 2020-11-27 06:41

    Simplest solution is to do a :

    $array = urldecode(http_build_query($array));
    

    Below is sample code where this is used in real life :

    https://gist.github.com/gayanhewa/142c48162f72e68a4a23

    When you have nested $params section in the above gist it will parse it accordingly and prepare it for posting via curl.

    0 讨论(0)
  • 2020-11-27 06:42
    function http_build_query_for_curl( $arrays, &$new = array(), $prefix = null ) {
    
        if ( is_object( $arrays ) ) {
            $arrays = get_object_vars( $arrays );
        }
    
        foreach ( $arrays AS $key => $value ) {
            $k = isset( $prefix ) ? $prefix . '[' . $key . ']' : $key;
            if ( is_array( $value ) OR is_object( $value )  ) {
                http_build_query_for_curl( $value, $new, $k );
            } else {
                $new[$k] = $value;
            }
        }
    }
    
    $arrays = array(
        'name' => array(
            'first' => array(
                'Natali', 'Yura'
            )
        )
    );
    
    
    http_build_query_for_curl( $arrays, $post );
    
    print_r($post);
    
    0 讨论(0)
  • 2020-11-27 06:47

    The cURL option CURLOPT_POSTFIELDS will accept either a string or simple array but not a nested array. Attempting to do so will generate the Array to string conversion error.

    However http_build_query() can handle a nested array so use it to convert the $_POST array to a string then send that string instead. So where you have;

    curl_setopt($ch, CURLOPT_POSTFIELDS, $_POST);
    

    use this instead;

    curl_setopt($ch, CURLOPT_POSTFIELDS, urldecode(http_build_query($_POST)));
    
    0 讨论(0)
  • 2020-11-27 06:48
    $post = "ac=on&p=1&pr[]=0&pr[]=1&a[]=3&a[]=4&pl=on&sp[]=3&ct[]=3&s=1&o=0&pp=3&sortBy=date";
    parse_str($post,$fields); 
    
    $url = 'http://example.com/';
    
    
    //open connection
    $ch = curl_init();
    
    //set the url, number of POST vars, POST data
    curl_setopt($ch,CURLOPT_URL, $url);
    curl_setopt($ch,CURLOPT_POST, true);
    curl_setopt($ch,CURLOPT_POSTFIELDS, $fields);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
    
    //execute post
    $result = curl_exec($ch);
    
    //close connection
    curl_close($ch);
    
    0 讨论(0)
提交回复
热议问题