I'm using PHP 8 & HTML5. My browser is current Chrome. The server creates a string, usually pulled from a database field: {"Name":"The big Test","Str":"Johnny\'s back yard has a sign that says \"No Shouting\". We\'re \"NOT\" SHOUTING!"} This is valid JSON. When I transfer it to the client the string changes. All the escape back slashes disappear. {"Name":"The big Test","Str":"Johnny's back yard has a sign that says "No peeing in the POOL!". We're "NOT" gonna do it!"} This is NOT valid JSON. I'd love to see docs on what is causing this. I need to transfer the string into a string literal on the client side and then JSON.parse the string. The single quotes in the string must be escaped because the string literal on the client is denoted by single quotes. <?php $jsn = '{"Name":"The big Test","Str":"Johnny\'s back yard has a sign that says \"No Shouting\". We\'re \"NOT\" SHOUTING!"}'; echo $jsn; //This echos the jsn. The back slashes are in the string. It is valid JSON. ?> <html> <body> <script> console.log('<?= $jsn?>'); //This shows the string without the escape back slashes var obj = JSON.parse('<?= $jsn?>'); //this line crashes javascript </script> </body></html> Code (markup):
Untested, but try add few more backslashes especially for the single quotes, perhaps? This way you won't lose the singles, i.e: <?php $jsn = '{"Name":"The big Test","Str":"Johnny\\\'s back yard has a sign that says \"No Shouting\". We\\\'re \"NOT\" SHOUTING!"}'; ?> PHP:
Thanks that didn't work. Here is the solution: https://stackoverflow.com/questions...s-from-php-to-javas#comment135192782_76680163
The entire point of JSON.parse is to decode it. If you don't want it decoded, why are you parsing it? Much less trying to output the PARSED Object? Shouldn't you be iterating the array to output its COMPONENTS? Or are you literlly just trying to assign the JSON to that variable, in which case just do it! I think what you're trying to do should be just this: let obj = <?= $jsn ?>; Code (markup): That way it becomes the declared object. Because what you want it to output in the <script> tag is: let obj = {"Name":"The big Test","Str":"Johnny\'s back yard has a sign that says \"No Shouting\". We\'re \"NOT\" SHOUTING!"}; Code (markup): JSON being a valid JavaScript construct, can just be assigned if you're doing it SERVER SIDE. Also since it uses double quotes as the string containers, technically you do not need to escape the singles.
Jason: Thanks for your response. "let obj = <?= $jsn ?>;" - exactly! That's what ADyson on stackoverflow recommended. I just didn't realize that a JSON string (without the string denotation) IS a Javascript object. I'm using that technique now on all my server -> client object transfers. It's working on all of them perfectly, including 1 whopping big object. You are correct! I no longer need to escape the single quotes. Thanks.
Glad to help. That's the thing that's really funny about them. JSON is literally just a string of JavaScript code; specifically an "object literal" declaration, though it has a few rules JS code does not. Like single quotes are invalid for mapping strings, and quotes aren't optional for indexes. { test : "test value" } // valid JS, invalid JSON { 'test' : 'test value' } // valid JS, invalid JSON That's the thing that's always tripping me up with them. When it comes to JSON.parse the only reason to use it is if you have a JSON string in JS you need to turn into an object, and the only place that "really" happens is for AJAX transfers be it via XMLHttpRequest or "fetch"... and even then we have the means to get around that "now" (if by now you mean the past 15 years). See, if you set XMLHttpRequest.responseType to "json" your instance::response will be the JSON object, so you don't need to "Waste time" calling JSON.parse() { const x = Object.assign( new XMLHttpRequest(), { responseType : "json", mimeType = "application/json", onload : (e) => { if (e.currentTarget.status == 200) { console.log( "Request OK, recieved", console.log(e.currentTarget.response); ); } else { throw new Error(`Request Error - Status Code ${e.currentTarget.status}`); } } } ); x.open("post", "testfile.json"); x.send(); } Code (markup): Event.currentTarget.response ends up your JSON as a JS object, no .parse needed. If you're working with JSON like you are, outputting it in the markup or as JS code might not be the best way of handling things. You might want to consider making it a separate request via XMLHttpRequest or "fetch" (I prefer the former) to leverage parallelism and to make it so your actual client side JS using it can be cached... though how and where you're sending it can vary that a lot!
I was aware of the differences between a JS object & a JSON string. It's not a problem, JS just converts it to a JS object. "separate request via XMLHttpRequest" - I used to use XMLHttpRequest but converted to JQuery ajax - I can't remember why. I'm pretty sure they're using XMLHttpRequest. I use fetch a pretty good bit too. It depends on the application. I'll move an object server to client during page load or on an ajax request. I also store JSON in form fields so in JS there is some i/o from/to a form field value. I didn't realize I can set the response type to JSON. Thanks. I have a potential problem with that though. If an error occurs on the server that I don't trap (and this mostly for dev) I can't see the error that the server threw. My way (ajax) I retrieve JSON no matter what (if I catch it) but as text. I send an object with a success or error property. If I miss the error I console.log the raw text response - the uncaught server error. Some form (and db) field values are JSON. JS needs to see the field values as objects. I JSON.parse/stringify i/o for that. "cached" - that's difficult because pretty much always, the reason for the JSON is data that changed and needs to be stored or read. Always learning something from you these days - thanks a lot. Cantankerous as you generally are you're an awful lot of help here on DP to people who will listen. DP should pay you for responses here. Are you involved with stackoverflow?
If there's an error, the server should be serving an HTTP error code (likely a 500) and you should parse it. I see people screw that up a lot and it always leaves me asking "why aren't you trapping errors?" I mean "not responding" you trap with try/catch or onerror, HTTP errors you trap with "status"... why don't people code in error responses and trapping? Nope, about a decade ago I had it out with them as they kept deleting my answers as "redundant" even though the answers they said I was redundant to were a decade out of date. Which seems to be a big problem of theirs, favoring old outdated answers over actual modern ones. Then we wonder why halfwits, morons, and fools create monuments to 1997 coding practices like bootcrap or failwind. Though their latest news induces hilarity. So few competent coders respond to questions there now and they've been coasting on legacy content for so long, they're diving for AI to answer people now. I'm so sure that will work out about as well as the lawyers who went full moron and trusted information from ChatGPT. Which is to say accidentally submitting fictional court cases completely made up by the AI and ending up sanctioned, fined, and under BAR review.
"HTTP error code (likely a 500)" didn't think to look for an HTTP error code. Then again, I don't really care what the code is if it'll tell me what the problem is. I think I need to rethink the client side (code's pretty old JQuery) but it does *try* to capture a non JSON error (like a 500 error). I could probably stand to rewrite it. This is the jquery code as it is now: function $sendAjax(prmUrl, prmFunc, prmParams, prmAsync) { if(!isset(prmAsync)) prmAsync = true; if(prmUrl == "") prmUrl = "AjaxHandler.php"; oRsp = null; dispAnimWaiting(); $.ajax({ url: prmUrl, async: prmAsync, method: "post", contentType: 'application/x-www-form-urlencoded; charset=UTF-8', cache: false, processData: false, data: prmParams }) .then(function(sResp) { if(isset(divAnimWaiting)) divAnimWaiting.remove(); try { sResp = sResp.replaceAll("'", "\'", sResp); sResp = sResp.replaceAll("null", "\"\"", sResp); oRsp = JSON.parse(sResp); } catch(error) { console.log("AJAX JSON ERROR: " + error.message); console.log("JSON: " + sResp); } if(isset(oRsp)) { //Keep prmFunc OUT OF the try if(oRsp.success || oRsp.success == "") { if(isset(prmFunc)) prmFunc(oRsp.success); //NOTE: This is INSIDE a try - if prmFunc crashes it'll land HERE. } else if(oRsp.error) { console.log("AJAX SVR ERROR: " + oRsp.error); if(!bAjaxIgnoreErr) alert("AJAX SVR ERROR: " + oRsp.error); } } }) .fail(function(sErr) { if(isset(divAnimWaiting)) divAnimWaiting.remove(); console.log("AJAX FAIL: "); for (let key in sErr) { let value = sErr[key]; console.log(key, value); } if(!bAjaxIgnoreErr && bDebug) alert(sErr); }) .always(function() { if(isset(divAnimWaiting)) divAnimWaiting.remove(); }); } Code (markup): "fictional court cases" that's pretty scary. I keep waiting for Alexa to start *telling* us what to do.
The issue you're facing is due to how PHP interprets strings within double quotes. When you echo the $jsn variable directly, PHP parses any escape sequences within the string. This includes the escaped single quotes (\'). However, when you use string interpolation with double quotes (like <?= $jsn ?>) within your HTML, PHP interprets the string literally. It doesn't process escape sequences, leading to the removal of the backslashes and causing invalid JSON on the client-side. Here's how you can fix the issue and ensure the string with escaped quotes reaches your JavaScript: Solution 1: Use JSON Encode Use the json_encode function in PHP to convert the string to valid JSON format before echoing it: PHP $jsn = '{"Name":"The big Test","Str":"Johnny\'s back yard has a sign that says \"No Shouting\". We\'re \"NOT\" SHOUTING!"}'; $encoded_json = json_encode($jsn); echo $encoded_json; Solution 2: Escape Single Quotes with PHP Escape the single quotes within the string itself using PHP before echoing: PHP $jsn = '{"Name":"The big Test","Str":"Johnny\'s back yard has a sign that says \"No Shouting\". We\'re \"NOT\" SHOUTING!"}'; $escaped_jsn = str_replace("'", "\\'", $jsn); // Escape single quotes with backslashes echo $escaped_jsn; Make sure your database is storing the data with the correct escaping for single quotes. Consider using a templating engine like Twig to simplify string interpolation and avoid potential escaping issues.