Search code examples
phpcurlput

PHP cURL API problem with nested arrays and http_build_query


Got cURL code working on terminal to change the forwarded phone number on an online SIP service (don't have access to the REST API server-side):

curl --request PUT --header "Accept: application/json" --header "Authorization: Basic abcdefABCDEFmysecretkey123456" -d '{"forwardings":[{"destination":"+447979123456","timeout":0,"active":true}]}' --header "Content-type: application/json" https://api.sipgate.com/v2/w0/phonelines/p0/forwardings

However my efforts to replicate this code in PHP are resulting in an {"error":"cannot parse content"} response:

$ch = curl_init();
$churl='https://api.sipgate.com/v2/w0/phonelines/p0/forwardings';
$chdata = array(
    'forwardings' => array(
        'destination' => '+447979123456',
        'timeout' => 0,
        'active' => true
    )
);
$chdata2 = http_build_query($chdata);
curl_setopt($ch, CURLOPT_URL, $churl);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    "Content-type: application/json",
    "charset: utf-8",
    "Accept: application/json",
    "Authorization: Basic abcdefABCDEFmysecretkey123456"
));
curl_setopt($ch, CURLOPT_POSTFIELDS, $chdata2);
$json = curl_exec($ch);
echo $json;
curl_close($ch);

What am I missing?


Solution

  • [from comments} I might be wrong, but I think json_encode does not properly handle nested arrays?

    json_encode handles them fine, you simply did not provide the correct input data structure to begin with.

    You are missing one array level in your data. 'forwardings' => array(...) needs to be 'forwardings' => array( array(...) )


    BTW/FYI/for anyone who might ever need it: An easy way to get the data structure you need, already in form of usable PHP code, based on the existing JSON, would be a combination of var_export and json_decode:

    var_export(json_decode('{"forwardings":[{"destination":"+447979123456","timeout":0,"active":true}]}', 1));
    

    gets you the following result,

    array (
      'forwardings' => 
      array (
        0 => 
        array (
          'destination' => '+447979123456',
          'timeout' => 0,
          'active' => true,
        ),
      ),
    )
    

    So you can slap a $chdata = in front of that and a ; at the end, and done.