1

Today I was testing PATCH calls to an API using PHP for the first time and to this moment I have not quite figured how to make them work.

I want to add a new parameter with it's value to an already existing set of parameters, I have set CURLOPT_CUSTOMREQUEST => "PATCH" as option and "Content-Type: application/json-patch+json" as the proper header. Despite my body being an array as the error first indicated when I parsed it into JSON, now it says that the entity is still not a well-formed application/json-patch+json.

I am totally lost as to why this could be, since other examples I have seen do not differ from what I wrote.

This is the existing set of parameters:

{
  "ac": "774",
  "allowed_clis": [
  "34774554114"
            ],
  "cc": "34",
  "cli": "34774554114",
  "id": 1512,
  "subscriber_id": 1512
}

What I am trying to achieve:

{
  "ac": "774",
  "allowed_clis": [
  "34774554114"
            ],
  "cc": "34",
  "cli": "34774554114",
  "id": 1512,
  "e164_to_ruri": true,
  "subscriber_id": 1512
}

This is my code:

$dataArray = [
    'op' => 'add', 
    'path' => '/e164_to_ruri', 
    'value' => true
];

function setPreferences($dataArray, $uri, $token){  
    $ch= curl_init();

    $options = array(
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_CUSTOMREQUEST => "PATCH",
        CURLOPT_POSTFIELDS => $dataArray,
        CURLOPT_URL => $uri,
        CURLOPT_HTTPHEADER => array("Content-Type: application/json-patch+json", "Authorization: Basic ".$token)
    );
    curl_setopt_array($ch, $options);

    $response = curl_exec($ch);

    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    return $response;
}

$response = setPreferences($dataArray, $uri, $token);
$response = json_decode($response, true);
print_r($response);

And finally, the response I get:

Array
(
    [message] => The entity is not a well-formed 'application/json-patch+json' document. Malformed JSON: Expected array or object at line 0, offset 0
    [code] => 400
)

To my limited knoledge, $dataArray is a well-formed array. So I don't understand where is this response coming from. Thank you so much for the help provided!

Berny
  • 121
  • 14
  • Your question title is pretty misleading. The actual error is "The entity is not a well-formed 'application/json-patch+json' document.", which is something *very* different. Also, if you compared the working code with the non-working code, you'd see another structure. The working one is a JSON array of JSON objects. You provided a PHP array which (probably) converts to a JSON object. – Ulrich Eckhardt Feb 03 '20 at 15:31
  • BTW: You can answer your own question and that's what you should do in this case. That said, as a new user here, please take the [tour] and read [ask]. – Ulrich Eckhardt Feb 03 '20 at 15:32
  • 1
    Your code is insecure. Do not switch off SSL verification. – Dharman Feb 03 '20 at 18:45
  • The tour was pretty generic advise to new users. The important point is, that you should remove your answer from the question and instead add a proper answer. The point of SO is to provide a question/answer knowledge base. An answered question is better than an unanswered one for that. Just to adhere to the structure. – Ulrich Eckhardt Feb 03 '20 at 19:32
  • You were right and I had a very bad day, my apologies for being such a jerk. I followed your advice and now both the title and the solution are as they should. Have a great day! @UlrichEckhardt – Berny Feb 06 '20 at 09:07
  • @Dharman yes! I know... But my bosses won't buy certificates, and the API won't admit self-signed ones, so this is really the only way. Being an internal thing, there should be less to be afraid of, but yes, it is still a pretty bad way of operating... – Berny Feb 06 '20 at 09:09

1 Answers1

2

As @UlrichEckhardt pointed out, all I needed to do is turn my data into a JSON array of JSON objects:

function setPreferences($uri, $token){  
    $ch= curl_init();

    $options = array(
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_CUSTOMREQUEST => "PATCH",
        CURLOPT_POSTFIELDS => '[{"op": "add", "path": "/e164_to_ruri", "value":true}]',
        CURLOPT_URL => $uri,
        CURLOPT_HTTPHEADER => array("Content-Type: application/json-patch+json", "Authorization: Basic ".$token)
    );
    curl_setopt_array($ch, $options);

    $response = curl_exec($ch);

    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    return $response;
}

$response = setPreferences($dataArray, $uri, $token);
$response = json_decode($response, true);
print_r($response);
Berny
  • 121
  • 14
  • **[You should not switch off `CURLOPT_SSL_VERIFYHOST` or `CURLOPT_SSL_VERIFYPEER`](https://paragonie.com/blog/2017/10/certainty-automated-cacert-pem-management-for-php-software)**. It could be a security risk! [Here is how to get the certificate bundle if your server is missing one](https://stackoverflow.com/a/32095378/1839439) – Dharman Feb 08 '20 at 17:49