0

I want to send json data via PUT to a REST service using the following php code:

$data = '{"api_key":"my-api-key","post":{"exception":["2015-04-10T11:09:51+00:00 ERR (3):\\nexception 'Exception' with message 'a simple exception' in \/private\/var\/www\/index.php:1\\nStack trace:\\n#0 {main}"],"access":["::1 - - [10\/Apr\/2015:13:08:17 +0200] \"GET \/index.php HTTP\/1.1\" 200 19039"]}}';
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");

curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data))
);

$response = curl_exec($curl);

As you can see I send valid json (validated by http://jsonlint.com/). On the side of the service I get the following json:

{"api_key":"my-api-key","post":{"exception":["2015-04-10T11:09:51+00:00 ERR (3):\\\\nexception \'Exception\' with message \'a simple exception\' in \\/private\\/var\\/www\\/index.php:1\\\\nStack trace:\\\\n#0 {main}"],"access":["::1 - - [10\\/Apr\\/2015:13:08:17 +0200] \\"GET \\/index.php HTTP\\/1.1\\" 200 19039"]}}

Validating this says I got a parse error. And this seems correct as I can't understand why further escaping is done like \\\\n. What am I doing wrong here?

tester
  • 3,977
  • 5
  • 39
  • 59
  • 2
    Dont build json manually, use `json_encode()`; – Steve Apr 10 '15 at 11:37
  • this link may help you http://stackoverflow.com/questions/27440171/how-to-send-a-post-request-to-the-restserver-api-in-php-codeigniter – Madhu Apr 10 '15 at 11:39
  • I did not build it manually, of course I use `json_encode()` but for this question I omitted the complex array. But the json string is definitely an output of `json_encode()`. The link you posted does not anything else I used in my question. – tester Apr 10 '15 at 11:47
  • 2
    Okay, seems to me I got fooled by `var_export($json, true)` which does the further escaping... – tester Apr 10 '15 at 11:59

1 Answers1

0

I doubt that this is a valid use of a PUT and should be a POST but that is just a technicality. If you can, make it a POST. The PUT is likely the root of the issue.

The CURLOPT_PUT uses CURLOPT_INFILE and CURLOPT_INFILESIZE

The URLOPT_CUSTOMREQUEST should work fine but it appears you have some RFC 3986 escaping going on for some unexplainable reason.

You may want to use rawurldecode ( ) on the Service Side.
This will give you (appears correct but I'm not the guy to verify):

{"api_key":"my-api-key","post":{"exception":["2015-04-10T11:09:51+00:00 ERR (3):\\nexception 'Exception' with message 'a simple exception' in \/private\/var\/www\/index.php:1\\nStack trace:\\n#0 {main}"],"access":["::1 - - [10\/Apr\/2015:13:08:17 +0200] \"GET \/index.php HTTP\/1.1\" 200 19039"]}}

Disclaimer: I have never used curl to POST Content-Type: application/json data.

You need to look at your Request Header and maybe Response. It would be interesting to see if you get the proper PUT Response.

  curl_setopt($ch, CURLOPT_HEADER, true);
  curl_setopt($ch, CURLINFO_HEADER_OUT, true);

Check your Request Header Content-Type

To get the headers:

The response Header will be in the returned transfer.
The Request Header will be in curl_getinfo()
The curl info will also include the HTTP Response Status. Which for a PUT should be 201 or 301 but not important.

  $data = curl_exec($ch);
  $skip = intval(curl_getinfo($ch, CURLINFO_HEADER_SIZE)); 
  $responseHeader = substr($data,0,$skip);
  $data= substr($data,$skip);
  $info = var_export(curl_getinfo($ch),true);
  echo $responseHeader . $info . $data;

If you still want to send the json without curl escaping it I have some thoughts on that. but there is probably a post on that subject here somewhere.

Misunderstood
  • 5,534
  • 1
  • 18
  • 25