cjson decoding error on identical code - php

Trying to post JSON data using PHP, but this text is displayed - {"message":"cjson decoding error","code":500,"error":true}
This is the data which is submitted via browser (used Live HTTP Headers plugin to get it):
{"nodes":[{"id":"fbm:n#1445506477266","type":"bookmark","parentId":"ROOT","refId":null,"href":"","text":"[New Bookmark]","desc":"","tags":"","cr":1445506584}],"revision":1,"token":"MTQ0NTUwNjQ3Ny4yOS1O9m2hacygwtDuox8/fHtN/efVUtNC9RvMlQbPAS+gwg=="}
This is my data:
json_encode(array("nodes"=>array(array("id"=>"fbm:n#1445506477266", "type"=>"bookmark", "parentId"=>"ROOT","refId"=>null,"href"=>"","text"=>"[New Bookmark]","desc"=>"","tags"=>"","cr"=>1445506584)), "revision"=>1,"token"=>"MTQ0NTUwNjQ3Ny4yOS1O9m2hacygwtDuox8/fHtN/efVUtNC9RvMlQbPAS+gwg=="))
When I print my data, I get exactly the same (except that json_encode function escapes / with \, but I read it doesn't matter in JSON). So here's the output of my data
{"nodes":[{"id":"fbm:n#1445506477266","type":"bookmark","parentId":"ROOT","refId":null,"href":"","text":"[New Bookmark]","desc":"","tags":"","cr":1445506584}],"revision":1,"token":"MTQ0NTUwNjQ3Ny4yOS1O9m2hacygwtDuox8/fHtN/efVUtNC9RvMlQbPAS+gwg=="}
As you see, everything is identical (except ). Even used Beyond Compare utility to compare every character of of the code between these, no differences.
How it comes the code still returns decode error? Tried using JSON_UNESCAPED_SLASHES as well (so no slashes are added), no result.

It seems your token is not true.
you can check with this code ;
$a = json_encode(array("nodes"=>array(array("id"=>"fbm:n#1445506477266", "type"=>"bookmark", "parentId"=>"ROOT","refId"=>null,"href"=>"","text"=>"[New Bookmark]","desc"=>"","tags"=>"","cr"=>1445506584)), "revision"=>1,"token"=>"MTQ0NTUwNjQ3Ny4yOS1O9m2hacygwtDuox8/fHtN/efVUtNC9RvMlQbPAS+gwg=="));
print_r($a);
echo '<br>';
echo '{"nodes":[{"id":"fbm:n#1445506477266","type":"bookmark","parentId":"ROOT","refId":null,"href":"","text":"[New Bookmark]","desc":"","tags":"","cr":1445506584}],"revision":1,"token":"MTQ0NTUwNjQ3Ny4yOS1O9m2hacygwtDuox8/fHtN/efVUtNC9RvMlQbPAS+gwg=="}';
Edit: JSON_UNESCAPED_SLASHES is working for me.
$a = array("nodes"=>array(array("id"=>"fbm:n#1445506477266", "type"=>"bookmark", "parentId"=>"ROOT","refId"=>null,"href"=>"","text"=>"[New Bookmark]","desc"=>"","tags"=>"","cr"=>1445506584)), "revision"=>1,"token"=>"MTQ0NTUwNjQ3Ny4yOS1O9m2hacygwtDuox8/fHtN/efVUtNC9RvMlQbPAS+gwg==");
json_encode($a,JSON_UNESCAPED_SLASHES);
print_r($a);
echo '<br><br><br>';
echo '{"nodes":[{"id":"fbm:n#1445506477266","type":"bookmark","parentId":"ROOT","refId":null,"href":"","text":"[New Bookmark]","desc":"","tags":"","cr":1445506584}],"revision":1,"token":"MTQ0NTUwNjQ3Ny4yOS1O9m2hacygwtDuox8/fHtN/efVUtNC9RvMlQbPAS+gwg=="}';

Related

Does echo and print not work in the 'live' version of php?

So I'm quite new to programming, and I have nothing else to describe it but a live script, so please correct me with the official term. Anyway, a while ago, I made this bot in php and ran it locally in my browser using xampp on my mac. I could very easily use echo and print_r to print arrays and whatever to the webpage. The script would only run if I reloaded the page, so this is what i'm talking about as 'not live'. Now I have started trying to make a messenger bot in PHP, and i'm using cloud9. I also see the script in a browser, but here, I can only see products of echo and print if they are simple strings I have entered, for example:
print_r("stack overflow is life");
This will print as expected in my browser. However, this is where me talking about 'live' script runs comes into play. Instead of reloading the page, it runs live. The messenger bot will always be active on the server, and it instantly replies to a message sent to it as wanted. I use this code:
/* receive and send messages */
$input = json_decode(file_get_contents('php://input'), true);
file_put_contents("fb.txt", file_get_contents('php://input'));
echo ("<pre>"); print_r($input);
echo ("</pre>");
Now, in this case, the $input is not printed. I see nothing. Now I don't know if this is to do with live server response, or what, but I need to know how to see this is the browser. And I have tested to see if there actually is a successfully converted JSON to array, because I am able to use the info in $input to reply to my facebook messaged and the bot works. I can also output the JSON to a txt file, and see it there, but there is no <pre> tags so it is hard to read, and I want the nice clean array to see in the browser. All code revolves around this, so it is very important.
So you are writing the raw input to the file and json decoding it separately. So it is quite possible you are not actually getting valid json.
If you do pass invalid json, json_decode returns NULL which is why you see that when you var_dump - so you have to call json_last_error to be sure it worked.
From Docs:
http://php.net/manual/en/function.json-decode.php
Returns the value encoded in json in appropriate PHP type. Values true, false and null are returned as TRUE, FALSE and NULL respectively. NULL is returned if the json cannot be decoded or if the encoded data is deeper than the recursion limit.
You should really check if json_decode works, here is an example to demonstrate:
<?php
$badjson = '{bad:"json"}';
$decoded = json_decode($badjson);
if(json_last_error()!==JSON_ERROR_NONE){
echo "Json Decode Failed: ".json_last_error_msg();
}else{
var_dump($decoded);
}
echo "\n---\n";
$goodjson = '{"property":"value"}';
$decoded = json_decode($goodjson);
if(json_last_error()!==JSON_ERROR_NONE){
echo "Json Decode Failed: ".json_last_error_msg();
}else{
var_dump($decoded);
}
See it in action here: http://sandbox.onlinephpfunctions.com/code/3a07e57f4cd01bd63d2945d5e367bbb0a6158195
See PHP Docs: http://php.net/manual/en/function.json-last-error.php
You can use a syntax checker to find the problem with your json e.g. http://jsonlint.com/
A common issue if the json is manually created is failing to wrap properties in double quotes e.g. {property:"value"} is invalid while {"property":"value"} is valid.
Note the reason you have to check json_last_error, and can't rely on NULL meaning it failed is because json_decode('NULL'); would return NULL and that would be correct.
Not sure what is cloud9.
For debug you can try var_dump() function. It will print onto your browser data type and data values, because there could be different type of "nothing". It's not a better way for debugging but a naive one. For better: check debug and breakpoint possibilities in this cloud9.
var_dump() can eat as many arguments as you like, so it's handy to dump everything with php input too to check what comes and how it changes.

Why does PHP replace pluses with spaces in $_COOKIE?

So from my understanding of PHP and cookies, if I use the setcookie() function, then I get a cookie that is automatically url encoded. And when I go to the $_COOKIE array, I should get the cookie back, automatically url decoded. Problem is, it seems to be decoding the cookie twice when I look in $_COOKIE.
Say I have a cookie whose value is "Name|ID|Email", for example:
Joe|123|my+email#somewhere.com
This would be encoded as:
Joe%7C123%7Cmy%2Bemail%40somewhere.com
Notice the plus sign is encoded, so theoretically I ought to get it back if I decode it. Since this is automatically done in $_COOKIE, I ought to get back what I started with. But instead, I'm getting back:
Joe|123|my email#somewhere.com
Notice the space where the plus used to be. This is what I would expect if I ran an additional urldecode() on the cookie. But I'm not, so I have no idea why I would be getting a space instead of a plus.
Another interesting twist. A refresh on the page seems to produce the correct output. Any ideas why it's behaving like this?
FYI, to set the initial cookie, I use javascript and escape() the script to produce the encoded string. Might this be an hand off issue between javascript and PHP?
Thoughts would be appreciated.
It's worth noting that both "%20" and "+" are valid encodings of a space character. Per the Wikipedia article on URL encoding (emphasis added):
When data that has been entered into HTML forms is submitted, the form
field names and values are encoded and sent to the server in an HTTP
request message using method GET or POST, or, historically, via email.
The encoding used by default is based on a very early version of the
general URI percent-encoding rules, with a number of modifications
such as newline normalization and replacing spaces with "+" instead of
"%20". The MIME type of data encoded this way is
application/x-www-form-urlencoded, and it is currently defined (still
in a very outdated manner) in the HTML and XForms specifications.
More specifically related to PHP and JavaScript, see the top answer on this question:
When to encode space to plus (+) or %20?
Firstly, PHP will always run before JavaScript - it's server side rather than client side so the cookie you set with JavaScript won't actually be available to PHP until you refresh the page (hence that issue).
Next JavaScript has different ways to encode the strings; only one will work with PHP automatically.
So:
document.cookie = "testuser=" + "Joe|123|my+email#somewhere.com";
// Joe|123|my email#somewhere.com (when decoded by PHP)
document.cookie = "testuser=" + escape("Joe|123|my+email#somewhere.com");
// Joe|123|my email#somewhere.com (when decoded by PHP)
document.cookie = "testuser=" + encodeURI("Joe|123|my+email#somewhere.com");
// Joe|123|my email#somewhere.com (when decoded by PHP)
document.cookie = "testuser=" + encodeURIComponent("Joe|123|my+email#somewhere.com");
// Joe|123|my+email#somewhere.com
So, try this for the sake of a test (remember you'll need to refresh the page to see the cookie value):
<html>
<head>
<title>Cookie Juggling</title>
<script type="text/javascript">
document.cookie = "testuser=" + encodeURIComponent("Joe|123|my+email#somewhere.com");
</script>
</head>
<body>
<div><?php echo !empty($_COOKIE['testuser']) ? $_COOKIE['testuser'] : "Cookie not set yet"; ?></div>
</body>
</html>
If you don't want to automatically encode the cookie, you can use setrawcookie function.
The exception with this function is, you can not use these characters: (,; \t\r\n\013\014) :
setrawcookie("NAME","Joe|123|my+email#somewhere.com");
# Output in browser:
Joe|123|my+email#somewhere.com
# Output in PHP `echo $_COOKIE['NAME']`:
Joe|123|my email#somewhere.com
Tested with PHP 5.3
setcookie("NAME","Joe|123|my+email#somewhere.com");
# Output in browser:
Joe%7C123%7Cmy%2Bemail%40somewhere.com
# Output in PHP echo $_COOKIE['NAME']`:
Joe|123|my+email#somewhere.com
now : As an alternative way, you can use setcookie(), and rawurldecode() to decode it:
echo rawurldecode($_COOKIE['NAME'])

Why doesn't urlencode and urldecode work?

here's the code i'm using:
$from=urldecode($_GET['from']);
$str =urldecode("%2B");
echo "$str<br>";
echo "$from<br>";
and here's part of the URL: from=%2B995594262653
why does this echo
+
995594262653
? (note, there's a space in front of the number).
i am using $str to check if the function works at all. apparently, it works for a simple %2B. What could be an issue?
It is working, but you need to realise that PHP will automatically urldecode the data it in puts in the $_GET array. You are doing it a second time and transforming the input even more.
When your script runs, $_GET['from'] contains +995594262653
When you run that value through urldecode, the + gets transformed to a space.

Remove double-quotes from a json_encoded string on the keys

I have a json_encoded array which is fine.
I need to strip the double-quotes on all of the keys of the json string on returning it from a function call.
How would I go about doing this and returning it successfully?
Thanks!
I do apologise, here is a snippet of the json code:
{"start_date":"2011-01-01 09:00","end_date":"2011-01-01 10:00","text":"test"}
Just to add a little more info:
I will be retrieving the JSON via an AJAX request, so if it would be easier, I am open to ideas in how to do this on the javascript side.
EDITED as per anubhava's comment
$str = '{"start_date":"2011-01-01 09:00","end_date":"2011-01-01 10:00","text":"test"}';
$str = preg_replace('/"([^"]+)"\s*:\s*/', '$1:', $str);
echo $str;
This certainly works for the above string, although there maybe some edge cases that I haven't thought of for which this will not work. Whether this will suit your purposes depends on how static the format of the string and the elements/values it contains will be.
TL;DR: Missing quotes is how Chrome shows it is a JSON object instead of a string. Ensure that you have Header('Content-Type: application/json; charset=UTF8'); in PHP's AJAX response to solve the real problem.
DETAILS:
A common reason for wanting to solve this problem is due to finding this difference while debugging the processing of returned AJAX data.
In my case I saw the difference using Chrome's debugging tools. When connected to the legacy system, upon success, Chrome showed that there were no quotes shown around keys in the response according to the debugger. This allowed the object to be immediately treated as an object without using a JSON.parse() call. Debugging my new AJAX destination, there were quotes shown in the response and variable was a string and not an object.
I finally realized the true issue when I tested the AJAX response externally saw the legacy system actually DID have quotes around the keys. This was not what the Chrome dev tools showed.
The only difference was that on the legacy system there was a header specifying the content type. I added this to the new (WordPress) system and the calls were now fully compatible with the original script and the success function could handle the response as an object without any parsing required. Now I can switch between the legacy and new system without any changes except the destination URL.

json_encode won't escape newlines

Firstly, I have search Stack Overflow for the answer, but I have not found a solution that works.
I am using an MVC framework (yii) to generate some views and throw them in an array. Each view is a card, and I have an array of cards ($deck) as well as an array of arrays of cards ($hands, the list of hands for each player). I'm simply trying to set a javascript variable on the front-end to store the hands created in PHP. My view has, it is worth noting, multiple lines. In fact, my current test view consists only of:
test
test
I therefore used json_encode, but it's giving me the following error when I use $.parseJSON():
Uncaught SyntaxError: Unexpected token t
I read elsewhere that it is required (for whatever reason) to use json_encode twice. I have tried this, but it does not help.
With a single json_encode, the output of echoing $hands (followed by an exit) looks pretty healthy:
[["test\ntest","test\ntest","test\ntest","test\ntest", etc...
But when I do not exit, I get a syntax error every time.
Edit: Here is a sample of my code. Note that $cards is an array of HTML normally, but in my simplified case which still errors, includes only the two lines of 'test' as mentioned above.
$deck = array();
foreach ($cards as $card) {
$deck[] = $this->renderPartial('/gamePieces/cardTest',
array('card'=>$card), true);
}
$hands = Cards::handOutCards($deck, $numCards , $numPlayers);
$hands = json_encode($hands);
echo $hands; exit;
With JavaScript, I am doing the following:
var hands = $.parseJSON('<?php echo json_encode($hands); ?>');
It errors on page load.
Any help would be appreciated!
Thanks,
ParagonRG
var hands = $.parseJSON('<?php echo json_encode($hands); ?>');
This will result in something like:
var hands = $.parseJSON('{"foobar":"baz'"}');
If there are ' characters in the encoded string, it'll break the Javascript syntax. Since you're directly outputting the JSON into Javacript, just do:
var hands = <?php echo json_encode($hands); ?>;
JSON is syntactically valid Javascript. You only need to parse it or eval it if you receive it as a string through AJAX for instance. If you're directly generating Javascript source code, just embed it directly.

Categories