1

The problem is simple to understand and demonstrate.

This code works fine:

<?php
    $title = array("dfg","sdfsdg","asfas","Sdfh","Ssdth","Csdgo");
    $title_json = json_encode($title);
?>
<script>
    var obj = JSON.parse('<?= $title_json; ?>');
    console.log(obj);
</script>

This code does not:

<?php
    $title = array("Is President Trump still using his old Android phone?","Trump sets a dizzying WH pace in first days","Trumps White House Charm Offensive a Contrast to Solitary Obama","The inside story of a basketball teen so tall, he doesn't look real","Scientists say they are closer to making Star Wars holograms","Sperm theft lawsuit leaves appeals court weighing how much a life is worth","Call it Smunday: Heinz pushing to make Super Bowl Monday a national holiday");
    $title_json = json_encode($title);
?>
<script>
    var obj = JSON.parse('<?= $title_json; ?>');
    console.log(obj);
</script>

Outputs error in console: Uncaught SyntaxError: missing ) after argument list - (index):20 where line 20 is one with JSON.parse and if you look at the source code of the page, the line reads:

var obj = JSON.parse('["Is President Trump still using his old Android phone?","Trump sets a dizzying WH pace in first days","Trump's White House Charm Offensive a Contrast to Solitary Obama","The inside story of a basketball teen so tall, he doesn't look real","Scientists say they are closer to making 'Star Wars' holograms","Sperm theft lawsuit leaves appeals court weighing how much a life is worth","Call it 'Smunday': Heinz pushing to make Super Bowl Monday a national holiday"]');

You may notice that the two code samples are exactly the same, the arrays even have the same length, the only difference is that the strings are longer in the second one. Does this mean there's a maximum length to the strings that can be parsed by JSON?

Mark Kramer
  • 3,134
  • 7
  • 34
  • 52
  • 2
    Note that where you've shown the line as seen in the browser, the colour-based syntax highlighting that SO added to your code is hinting at the problem. – nnnnnn Feb 21 '17 at 05:49
  • These days you can use `\`` (aka. backticks) to wrap strings. (ie `var obj = JSON.parse(\`["Is Pre..."]\`);` – haxxxton Feb 21 '17 at 05:49
  • @nnnnnn Indeed, if the IDE I was using shared that highlighting I probably never would have needed to ask this question, I would have known it was the apostrophes. Of course, I still wouldn't have known I didn't even need JSON.parse and would have spent a while trying to figure out how to escape the apostrophes. – Mark Kramer Feb 21 '17 at 05:55
  • 1
    Do be careful though, these no quote answers do assume that there's never a case where your `json_encode` [fails silently](http://stackoverflow.com/questions/9098507/why-is-this-php-call-to-json-encode-silently-failing-inability-to-handle-singl) (say from being provided bad data). as this will result in the js on the front side looking like `var obj = ;` which will throw a `Uncaught SyntaxError: Unexpected token ;` – haxxxton Feb 21 '17 at 05:57
  • 1
    The array is populated from a database that is itself populated by entries in a form so assuming I set up my form validation correctly there should be no bad data. – Mark Kramer Feb 21 '17 at 05:58
  • @MarkKramer, agreed, merely a warning in the case where you try to do things like `json_encode` things like malformed UTF-8 characters ([See this example](http://stackoverflow.com/questions/9098507/why-is-this-php-call-to-json-encode-silently-failing-inability-to-handle-singl)) – haxxxton Feb 21 '17 at 06:01

1 Answers1

9

Your JSON data contains '. So if you inject that data into a ' delimited string literal, that string literal will be closed prematurely and cause a syntax error. Simple example:

var foo = '{"key": "This key's value"}';

You should notice that if you look at the generate JavaScript source.

There is no need to use JSON.parse here. The injected JSON can be interpreted as a JavaScript object/array literal:

var obj = <?= $title_json; ?>;

See also: How to pass variables and data from PHP to JavaScript?

Community
  • 1
  • 1
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • Then in what circumstance would I need JSON.parse, I was just following an article that said that is how you pass PHP arrays into javascript. – Mark Kramer Feb 21 '17 at 05:48
  • 3
    You need `JSON.parse` if you have a string value containing JSON. That would happen for example if you did an `XMLHTTPRequest` and get JSON as response. But here you are generating the JavaScript source from PHP. Since JSON can be parsed as JavaScript source code (if it is in the right location) you can directly inject it into the source as an object/array instead of injecting it as the content of a string literal. As you noticed, that is error prone, because certain characters and character sequences have different meaning inside a string literal. – Felix Kling Feb 21 '17 at 05:48
  • 1
    Maybe this is a bit far fetched, but consider this example: if you just had a number value, you'd probably do `var n = <= 42;>;` instead of `var n = eval('<= 42;>');`. The `eval` is unnecessary because `42` is a valid number literal in JS (where this example falls short is that `eval` wouldn't work anyway if it wasn't valid JS code, but ¯\\_(ツ)_/¯). – Felix Kling Feb 21 '17 at 05:57