Rob
Rob

Reputation: 70

Escaping quotes in a javascript object generated from PHP

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:

  1. Do some sort of encoding on the user-entered data before it gets saved to the database
  2. Escape the special characters when loading from the MySQL (using 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).
  3. Escape the special characters in javascript, somehow. But I don't know how I'd do this.

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

Answers (3)

Rob
Rob

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

kmoser
kmoser

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

user3477882
user3477882

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

Related Questions