Use PHP functions in JavaScript

JavaScript json_encode

Returns the JSON representation of a value

1
2
3
4
56
7
8
9
1011
12
13
14
1516
17
18
19
2021
22
23
24
2526
27
28
29
3031
32
33
34
3536
37
38
39
4041
42
43
44
4546
47
48
49
5051
52
53
54
5556
57
58
59
6061
62
63
64
6566
67
68
69
7071
72
73
74
7576
77
78
79
8081
82
83
84
8586
87
88
89
9091
92
93
94
9596
97
98
99
100101
102
103
104
105106
107
108
109
110111
112
113
114
115116
117
118
119
120121
122
123
124
125126
127
128
129
130131
132
133
134
135136
137
138
139
140141
142
143
144
145146
147
148
149
150151
152
153
154
155156
157
158
159
160161
162
163
164
165166
function json_encode (mixed_val) {
    // Returns the JSON representation of a value  
    // 
    // version: 1008.1718
    // discuss at: http://phpjs.org/functions/json_encode    // +      original by: Public Domain (http://www.json.org/json2.js)
    // + reimplemented by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +      improved by: Michael White
    // +      input by: felix
    // +      bugfixed by: Brett Zamir (http://brett-zamir.me)    // *        example 1: json_encode(['e', {pluribus: 'unum'}]);
    // *        returns 1: '[\n    "e",\n    {\n    "pluribus": "unum"\n}\n]'
    /*
        http://www.JSON.org/json2.js
        2008-11-19        Public Domain.
        NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
        See http://www.JSON.org/js.html
    */
    var retVal, json = this.window.JSON;    try {
        if (typeof json === 'object' && typeof json.stringify === 'function') {
            retVal = json.stringify(mixed_val); // Errors will not be caught here if our own equivalent to resource
                                                                            //  (an instance of PHPJS_Resource) is used
            if (retVal === undefined) {                throw new SyntaxError('json_encode');
            }
            return retVal;
        }
         var value = mixed_val;
 
        var quote = function (string) {
            var escapable = /[\\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
            var meta = {    // table of character substitutions                '\b': '\\b',
                '\t': '\\t',
                '\n': '\\n',
                '\f': '\\f',
                '\r': '\\r',                '"' : '\\"',
                '\\': '\\\\'
            };
 
            escapable.lastIndex = 0;            return escapable.test(string) ?
                            '"' + string.replace(escapable, function (a) {
                                var c = meta[a];
                                return typeof c === 'string' ? c :
                                '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);                            }) + '"' :
                            '"' + string + '"';
        };
 
        var str = function (key, holder) {            var gap = '';
            var indent = '    ';
            var i = 0;          // The loop counter.
            var k = '';          // The member key.
            var v = '';          // The member value.            var length = 0;
            var mind = gap;
            var partial = [];
            var value = holder[key];
             // If the value has a toJSON method, call it to obtain a replacement value.
            if (value && typeof value === 'object' &&
                typeof value.toJSON === 'function') {
                value = value.toJSON(key);
            } 
            // What happens next depends on the value's type.
            switch (typeof value) {
                case 'string':
                    return quote(value); 
                case 'number':
                    // JSON numbers must be finite. Encode non-finite numbers as null.
                    return isFinite(value) ? String(value) : 'null';
                 case 'boolean':
                case 'null':
                    // If the value is a boolean or null, convert it to a string. Note:
                    // typeof null does not produce 'null'. The case is included here in
                    // the remote chance that this gets fixed someday. 
                    return String(value);
 
                case 'object':
                    // If the type is 'object', we might be dealing with an object or an array or                    // null.
                    // Due to a specification blunder in ECMAScript, typeof null is 'object',
                    // so watch out for that case.
                    if (!value) {
                        return 'null';                    }
                    if ((this.PHPJS_Resource && value instanceof this.PHPJS_Resource) ||
                        (window.PHPJS_Resource && value instanceof window.PHPJS_Resource)) {
                        throw new SyntaxError('json_encode');
                    } 
                    // Make an array to hold the partial results of stringifying this object value.
                    gap += indent;
                    partial = [];
                     // Is the value an array?
                    if (Object.prototype.toString.apply(value) === '[object Array]') {
                        // The value is an array. Stringify every element. Use null as a placeholder
                        // for non-JSON values.
                         length = value.length;
                        for (i = 0; i < length; i += 1) {
                            partial[i] = str(i, value) || 'null';
                        }
                         // Join all of the elements together, separated with commas, and wrap them in
                        // brackets.
                        v = partial.length === 0 ? '[]' :
                                gap ? '[\n' + gap +
                                partial.join(',\n' + gap) + '\n' +                                mind + ']' :
                                '[' + partial.join(',') + ']';
                        gap = mind;
                        return v;
                    } 
                    // Iterate through all of the keys in the object.
                    for (k in value) {
                        if (Object.hasOwnProperty.call(value, k)) {
                            v = str(k, value);                            if (v) {
                                partial.push(quote(k) + (gap ? ': ' : ':') + v);
                            }
                        }
                    } 
                    // Join all of the member texts together, separated with commas,
                    // and wrap them in braces.
                    v = partial.length === 0 ? '{}' :
                            gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +                            mind + '}' : '{' + partial.join(',') + '}';
                    gap = mind;
                    return v;
                case 'undefined': // Fall-through
                case 'function': // Fall-through                default:
                    throw new SyntaxError('json_encode');
            }
        };
         // Make a fake root object containing our value under the key of ''.
        // Return the result of stringifying the value.
        return str('', {
            '': value
        });    
    } catch(err) { // Todo: ensure error handling above throws a SyntaxError in all cases where it could
                            // (i.e., when the JSON global is not available and there is an error)
        if (!(err instanceof SyntaxError)) {
            throw new Error('Unexpected error type in json_encode()');        }
        this.php_js = this.php_js || {};
        this.php_js.last_error_json = 4; // usable by json_last_error()
        return null;
    }}
external links: original PHP docs | raw js source

Examples

Running

1
json_encode(['e', {pluribus: 'unum'}]);

Should return

1
'[\n    "e",\n    {\n    "pluribus": "unum"\n}\n]'

Dependencies

No dependencies, you can use this function standalone.

Open syntax issues

php.js uses JsLint to help us keep our code consistent and prevent some common bugs.

Eventually we want all code to pass or at least take into consideration most fixes suggested by JsLint, following this JsLint configuration we’ve decided on.


Authors

Thanks to the following developers, you get to have json_encode goodness in JavaScript.

Comments

Add Comment
Use:
[CODE]
your_stuff('here');
[/CODE]
for proper code formatting
By submitting code here you are allowing us to use it in php.js hence dual licensing it under the MIT and GPL licenses

Gravatar
Brett Zamir
Apr 20th Permalink

q  Fixed in Git. Thanks for pointing out the problem, felix. Btw, one can't only check for a variable like that (as one can in PHP) since your example will also cause an undefined error. In JS, you have to test a variable as a property, including against the global:

e.g., these are ok:
if (window.someVar) {}
if (this.someVar) {}

but this is not:
if (someVar) {}

Gravatar
felix
Apr 20th Permalink

q  Hi

as already listed above, PHPJS_Resource is not defined. This triggers an unexpected error for me at least if I try to use this function standalone (FF 3.5.9).
How about changing lines ## 95-97 to:

if (PHPJS_Resource && value instanceof PHPJS_Resource) {                        
    throw new SyntaxError('json_encode');
}


?

Gravatar
Kevin van Zonneveld
7 Nov '09 Permalink

q  Excellent!

Gravatar
Brett Zamir
26 Oct '09 Permalink

q  Have made a fix (NULL to null) and added support for json_last_error(); see commits at http://github.com/kvz/phpjs/commits/master/

Gravatar
Kevin van Zonneveld
25 Oct '09 Permalink

q  @ Michael White: Ok great that you did the research on this Michael!

I've implemented your fixes:
http://github.com/kvz/phpjs/commit/cae72555c08c11ec416f1c8ecfcd5e42509cb46d

Gravatar
Michael White
20 Oct '09 Permalink

q  @kevin I didn't know what it returned because last time I ran into this in PHP I was encountering an infinite loop because of it (long story). However, I tested it in a simple script just now and I'm getting NULL output. It also throws a PHP error warning that the type is unsupported. This happens if a resource is present anywhere in the data to be encoded.

Gravatar
Brett Zamir
18 Oct '09 Permalink

q  @Michael: If you try it with a resource object, what does it return in PHP? See also my comment in json_decode().

Gravatar
Michael White
18 Oct '09 Permalink

q  The part that uses native browser JSON objects should be contained in a try/catch block and return the proper value in accordance with how PHP handles bad input. (The only bad input in PHP seems to be resource objects). Should we return "null" or an empty string or false here upon error?

try {
    return json.stringify(mixed_val);
}
catch(err) {
    return mixed_val;
}

Gravatar
Brett Zamir
18 Jun '09 Permalink

q  @T. J. Leahy: Fixed in SVN. Thanks for the report! See also my note at http://phpjs.org/functions/json_decode:456#comment_64602

Gravatar
T.J. Leahy
17 Jun '09 Permalink

q  This function should check to see if the browser has native JSON encoding first (IE8, FF 3.5) and use that when available. Would make it faster and safer then running the object against multiple regular expressions. See http://hacks.mozilla.org/2009/06/security-performance-native-json/

if (typeof JSON == "object" && typeof JSON.stringify == "function") {
    return JSON.stringify(str_json);
}



Contribute a New function

More functions

In this category

json_decode
» json_encode
json_last_error

Support us

spread the word:


Use any PHP function in JavaScript


These kind folks have already donated: @HalfWinter, Paulo Freitas, Andros Peña Romo, Nitin Gupta, @nikosdion, Anonymous, Anonymous and Shawn Houser.
<your name here>

Click here to lend your support to: phpjs and make a donation at www.pledgie.com !