Hi,

I've researched everywhere and cannot figure this out.

I am writing a test cUrl request to test my REST service:

// initialize curl handler
$ch = curl_init();

$data = array(
"products" => array ("product1"=>"abc","product2"=>"pass"));
$data = json_encode($data);

$postArgs = 'order=new&data=' . $data;

// set curl options
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLINFO_HEADER_OUT, TRUE);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postArgs);
curl_setopt($ch, CURLOPT_URL, 'http://localhost/store/rest.php');

// execute curl
curl_exec($ch);

This works fine and the request is accepted by my service and $_Post is populated as required, with two variables, order and data. Data has the encoded JSON object. And when I print out $_Post['data'] it shows:

{"products":{"product1":"abc","product2":"pass"}}

Which is exactly what is expected and identical to what was sent in.

When I try to decode this, json_decode() returns nothing!

If I create a new string and manually type that string, json_decode() works fine!

I've tried:

strip_tags() to remove any tags that might have been added in the http post utf8_encode() to encode the string to the required utf 8 addslashes() to add slashes before the quotes

Nothing works.

Any ideas why json_decode() is not working after a string is received from an http post message?

Below is the relevant part of my processing of the request for reference:

public static function processRequest($requestArrays) {
    // get our verb
    $request_method = strtolower($requestArrays->server['REQUEST_METHOD']);
    $return_obj = new RestRequest();
    // we'll store our data here
    $data = array();

    switch ($request_method) {
        case 'post':
            $data = $requestArrays->post;
            break;
    }

    // store the method
    $return_obj->setMethod($request_method);

    // set the raw data, so we can access it if needed (there may be
    // other pieces to your requests)
    $return_obj->setRequestVars($data);

    if (isset($data['data'])) {
        // translate the JSON to an Object for use however you want
        //$decoded = json_decode(addslashes(utf8_encode($data['data'])));
        //print_r(addslashes($data['data']));
        //print_r($decoded);
        $return_obj->setData(json_decode($data['data']));
    }
    return $return_obj;
 }
link|flag

75% accept rate
This may not be the problem (hence a comment instead of an answer), but you need to urlencode() the JSON string before sending with cURL. php.net/urlencode – Jonah Bron Dec 13 at 22:11
I encoded the JSON string before sending it into cURL, but the result is still that same. This is driving me insane! Thanks for the suggestion though. – mm2887 Dec 13 at 22:37
after if (isset($data['data'])) {, can you add a var_dump($data['data']); and post what it shows? – scoates Dec 13 at 23:17
It prints out: string(99) "{"products":{"product1":"abc","product2":"pass"}}" I then did the same var_dump for the JSON that is sent and it printed out: string(49) "{"products":{"product1":"abc","product2":"pass"}}" If I do the same thing on the urlencode() version of the JSON object it prints out: string(85) "%7B%22products%22%3A%7B%22product1%22%3A%22abc%22%2C%22product2%22%3A%22pass%22%7D%7D" – mm2887 Dec 13 at 23:49
I also tried preg_replace("[^A-Za-z0-9]", "", $data); on the string that is string(99) and nothing changed. – mm2887 Dec 14 at 1:12
show 4 more comments

2 Answers

old:

$return_obj->setData(json_decode($data['data']));

new:

$data = json_decode( urldecode( $data['data'] ), true );
$return_obj->setData($data);

try it im curious if it works.

link|flag
Didn't do anything :( – mm2887 Dec 13 at 22:29
up vote 0 down vote accepted

Turns out that when JSON is sent by cURL inside the post parameters & quot; replaces the "as part of the message encoding. I'm not sure why the preg_replace() function I tried didn't work, but using html_entity_decode() removed the &quot and made the JSON decode-able.

link|flag

Your Answer

 
or
never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.