Javascript decode JSON string which contains an encoded string

15,644

Solution 1

The problem that you're running into is that the output of json_encode is not meant to be used directly as a string in JavaScript.

json_encode outputs a usable JavaScript object:

<?php
$foo = new stdClass();
$foo->test='hello world';
$bar = new stdClass();
$bar->foo = json_encode($foo);
$encoded_string = json_encode($bar);
?>
var a = <?php $encoded_string ?>;
console.log(a.foo); // produces '{"test":"hello world"}'

If you want to needlessly parse the JSON output from a string value, you simply need to double encode $encoded_string:

<?php
$foo = new stdClass();
$foo->test='hello world';
$bar = new stdClass();
$bar->foo = json_encode($foo);
$encoded_string = json_encode(json_encode($bar));
?>
var aStr = <?php $encoded_string ?>;
var a = JSON.parse(aStr);
console.log(a.foo); //same as before

Of course, you should avoid using server side languages to generate JavaScript code, instead set up the data as either a data-* attribute or as a JSON source that can be requested with AJAX.

When the data is requested from the server (or from the attribute) it will be as a properly escaped JavaScript string, which is where JSON.parse will be necessary to parse the object.

Solution 2

Your code should be

$foo = new stdClass();
$foo->test='hello world';
$bar = new stdClass();
$bar->foo = $foo;
$encoded_string = json_encode($bar);

Just json encode once at the end, and decode once at the beginning at the other end.


As for the jsfiddle, you are not considering that the string literals go through additional decoding layer before they become "strings in javascript memory".

The correct way to setup the string literal in this case is (JS-JSON-JSON):

data = $.parseJSON('{"foo":"{\\\"test\\\":\\\"hello world\\\"}"}');
console.log($.parseJSON(data.foo));

And simply reversing the encoding steps you did works. http://jsfiddle.net/Jmjjp/2/

Solution 3

The problem is double encoding as JSON. The solution you want if you need to retain the data as a string is

$bar->foo = addslashes(json_encode($foo));

Share:
15,644
periklis
Author by

periklis

There are no stupid questions

Updated on June 05, 2022

Comments

  • periklis
    periklis almost 2 years

    I have the following PHP code:

        $foo = new stdClass();
        $foo->test='hello world';
        $bar = new stdClass();
        $bar->foo = json_encode($foo);
        $encoded_string = json_encode($bar);
    

    The $encoded_string contains:

    {"foo":"{\"test\":\"hello world\"}"}
    

    I want to parse this string from javascript (using jQuery's $.parseJSON for example):

    var data = $.parseJSON('{"foo":"{\"test\":\"hello world\"}"}');
    console.log(data);
    

    I would expect something like the following to be logged:

    Object {foo: '{"test":"hello world"}'}
    

    But I get an Unexpected token t error when running it (using chromium)

    How can I parse this json string in Javascript? Here's a fiddle if anyone wants to try.