Search code examples
phpcurlphp-curl

How to send a multidimensional array with PHP cURL without array keys from the nested arrays?


Introduction

So I'm trying to send form values as a query string to an API. The API expects a query string like this:

&name=Charles+Hansen&email=example@email.com&locations=23433&locations=23231&propertyTypes=APARTMENT&propertyTypes=TOWNHOUSE&message=test"

As you can see there are multiple "propertyTypes" and "locations" depending on how many property types or locations the user picks in the form. Because of that I have stored all $_POST data in a multidimensional array which looks like this, since I obviously can't have multiple keys with the same name "propertyTypes" or "locations":

Array
(
    [name] => Charles Hansen
    [email] => example@email.com
    [locations] => Array
        (
            [0] => 23433
            [1] => 23231
        )
    [propertyTypes] => Array
        (
            [0] => APARTMENT
            [1] => TOWNHOUSE
        )
    [message] => test
)

cURL does not support multidimensional arrays, therefore I first build the query myself before using it. This is my cURL function:

function sg_order($post_fields) {
    if($post_fields) {
        $query = http_build_query($post_fields);

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, 'https://example.com/order?orgKey=' . constant('ORG_KEY'));
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
          'Content-Type: application/x-www-form-urlencoded',                 
          'Content-Length: ' . strlen($query))
        );
        $result = curl_exec($ch);

        $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);

        if(curl_errno($ch)) {
          error_log('Curl error: ' . curl_error($ch) . $result);
        }else{
          error_log('Curl response: ' . $status);
        }
        curl_close($ch);

        return $result;
    }
}

orgKey is a required parameter for validation.

The problem

My problem is, that the query built by $query = http_build_query($post_fields); contains the keys for the nested arrays ([0], [1] etc.). The result of $query looks like this:

&name=Charles+Hansen&email=example@email.com&locations[0]=23433&locations[1]=23231&propertyTypes[0]=APARTMENT&propertyTypes[1]=TOWNHOUSE&message=test"

How do I get rid of the keys ([0], [1] etc.) so that the query looks exactly like what the API expects?

Additional info

  • I have no control over the API
  • I am not sending files, so a solution does not have to work with files

Solution

  • If you don’t want to write your own version of http_build_query, then I’d suggest you modify the version from this user comment in the manual, http://php.net/manual/en/function.http-build-query.php#111819

        $query = http_build_query($query);
        $query = preg_replace('/%5B[0-9]+%5D/simU', '%5B%5D', $query);
    

    They are replacing foo[xy] with foo[] here - since you don’t want to keep the [] either, just replace '%5B%5D' in the preg_replace call with an empty string instead.