Reputation: 70
I feel like this must surely be a duplicate of an oft-answered question, but I cannot find an answer that addresses my particular issue.
I am loading data from MySQL via PHP, including some strings and a JSON-encoded string. This data may contain special characters, entered by the user.
I then combine this data into a PHP array, then json_encode
it and read it into javascript using JSON.parse
.
My issue is that an apostrophe in any of these strings will interrupt the javascript, preventing the JSON.parse
from completing.
I think there are three ways to solve this:
htmlspecialchars()
or similar), though this will be difficult when loading data that's stored as a JSON string (I suppose I could decode it, then loop through and escape special characters in each element, then re-encode it).I would have to say that special character encoding is probably the single-most frustrating aspect of web development, as it causes me so many unexpected errors and I struggle to understand the different functions and when they should be used.
EDIT:
var feedback = JSON.parse('{"721103":[{"sessionid":"45","feedback":{"praise":["","",""],"development":["","",""]}},{"sessionid":"46","feedback":{"praise":["Test","Test's",""],"development":["","",""]}}') ;
The apostrophe in Test's
breaks the javascript
Upvotes: 2
Views: 1487
Reputation: 70
My attempts to edit @kmoser's answer with the actual solution that worked were rejected in peer review, so here's what worked. All credit to @kmoser:
$json_feedback = preg_replace( preg_quote('/\u/'), '\\\\\\\\u', json_encode( $feedback, JSON_HEX_APOS | JSON_HEX_QUOT ) );
It works by replacing singles and double quotes with hex strings when the data is retrieved from the MySQL database. For reasons I don't understand, that still broke the javascript, so I then did a preg_replace
to put an additional backslash before the escaped code.
Notice how many backslashes I had to put in to persuade the preg_replace to put in the additional backslash to prevent the javascript breaking. I may be able to get away with fewer backslashes, the number that appears here is mostly out of sheer frustration with this silly issue!
Upvotes: 1
Reputation: 9308
Don't munge user data before storing in the DB. You can munge it all you want after retrieving it.
I assume you're using PHP's json_encode() function to produce the JSON-encoded string, in which case you can use the JSON_HEX_APOS
option to encode apostrophes as \u0027
, e.g.:
json_encode( $a, JSON_HEX_APOS )
Where $a
is your PHP array. This should produce a JSON string devoid of actual apostrophes, which you can surround with apostrophes to create a Javascript string:
echo "var feedback = JSON.parse('" . json_encode( $a, JSON_HEX_APOS ) . "')";
Upvotes: 2
Reputation:
This should prevent your javascript from breaking:
var feedback = JSON.parse(`{"721103":[{"sessionid":"45","feedback":{"praise":["","",""],"development":["","",""]}},{"sessionid":"46","feedback":{"praise":["Test","Test's",""],"development":["","",""]}}]}`) ;
It uses ``, instead of ''. They work the same, but won't be affecting eachother.
I also corrected your json syntax error.
Upvotes: 3