Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't JSON.parse after json_encode doesn't work?

Why won't this work for me?

<script>
JSON.parse(<?php echo json_encode(array('test123', 'test456')); ?>);
</script>

I get this error:

SyntaxError: JSON.parse: unexpected non-whitespace character after JSON data

like image 539
Recovering Nerdaholic Avatar asked Apr 18 '14 02:04

Recovering Nerdaholic


2 Answers

JSON is valid Javascript already, so JSON.parse is not needed here. The following should work without a problem:

<script>
var obj = <?php echo json_encode(array('test123', 'test456')); ?>;
</script>

This will result in the following source on the page (which is perfectly valid JSON and Javascript):

<script>
var obj = ["test123", "test456"];
</script>

Direct Answer: Since the above doesn't technically answer your question, JSON.parse is intended to work with strings. You're not giving it a string, you're giving it an object (since, again, JSON is valid javascript). JSON.parse should work fine, if you actually put the value in single quotes, but you'll need to make sure it's escaped properly (single quotes inside of single quotes will obviously cause problems). But I would avoid dealing with the JSON as a string, given that it's unnecessary in this case.

like image 45
Colin M Avatar answered Nov 14 '22 21:11

Colin M


PHP's json_encode produces a string, but it's an actual string in memory, not one in PHP syntax, so it's not wrapped in quotes when echoed. When echoed into the context of JavaScript code, it prints perfectly valid JSON, but the JS interpreter would not see it as a string because it's not wrapped in quotes. Without them, JS sees an array denoted in literal syntax (because JSON borrows its own syntax from a subset of JS literal syntax). Thus, trying to parse it would throw an error.

If your code ran, this is what would actually show up in a the outputted source:

<script>
var obj = ["test123", "test456"];
</script>

As obj now holds an array (which was denoted in JS literal syntax), running it through JSON.parse would cause an error.

Think of it like a sentence you wrote in a string in PHP, then echoed:

<?php
$sentence = 'I like beer.':
echo $sentence;
?>

This would produce the output:

I like beer.

Notice no wrapping quotes. Now, imagine writing a chunk of JSON "by hand" and echoing it:

<?php
$json = '{"foo": "bar"}':
echo $json;
?>

This would output:

{"foo": "bar"}

Again, notice no wrapping quotes. That assignment to the variable $json produces the same string data in PHP as your call to json_encode. So echoing the output of your call also results in no quotes.

Now, look at that last output chunk--what would a JavaScript engine do if it ran across something like that?

So, to parse with JSON.parse, you need something JS will interpret as a string during the JS engine's parse. If you wrapped your PHP in single quotes as such:

<script>
var obj = '<?php echo json_encode(array('test123', 'test456')); ?>';
</script>

Then the output would be:

<script>
var obj = '["test123", "test456"]';
</script>

As this is a string in proper format, it is now JSON and could be passed to JSON.parse.

(Note: Simply wrapping in single quotes isn't safe, though, as the structure which PHP encoded may have a string within which contains a single quote. That would result in a syntax error in your JavaScript.)

As has been mentioned, none of this is necessary anyway--you can hand JS your non-quoted JSON and skip the parse because the JS interpreter will parse it as is and save you a step. I just wanted you to understand the mechanics. Hope I didn't confuse you... :(

JavaScript is the only language in which the direct output of JSON into a context which makes it no longer a string could actually produce something workable. This is because JSON syntax borrows from a subset of the JavaScript literal syntax.

Context is everything in this. For example, sending JSON to JavaScript over AJAX is different than the context you showed for trying to give JavaScript some JSON. In the case of AJAX, the response from the server to the AJAX code is a JS string in memory already. Whereas having PHP echo into JS code produces syntax for parsing by the JS engine, thus needing quotes to make it a string.

like image 150
JAAulde Avatar answered Nov 14 '22 22:11

JAAulde