PHP


JSON All Versions

Legacy Versions

1.0
2.0
3.0

PHP 4.x

4.0
4.1
4.2
4.3
4.4

PHP 5.x

5.0
5.1
5.2
5.3
5.4
5.5
5.6

PHP 7.x

7.0
7.1

JSON (JavaScript Object Notation) is a platform and language independent way of serializing objects into plaintext. Because it is often used on web and so is PHP, there is a basic extension for working with JSON in PHP.

This draft deletes the entire topic.

Examples

  • 106

    The json_decode() function takes a JSON-encoded string as its first parameter and parses it into a PHP variable.

    Normally, json_decode() will return an object of \stdClass if the top level item in the JSON object is a dictionary or an indexed array if the JSON object is an array. It will also return scalar values or NULL for certain scalar values, such as simple strings, "true", "false", and "null". It also returns NULL on any error.

    // Returns an object (The top level item in the JSON string is a JSON dictionary)
    $json_string = '{"name": "Jeff", "age": 20, "active": true, "colors": ["red", "blue"]}';
    $object = json_decode($json_string);
    printf('Hello %s, You are %s years old.', $object->name, $object->age);
    #> Hello Jeff, You are 20 years old.
    
    // Returns an array (The top level item in the JSON string is a JSON array)
    $json_string = '["Jeff", 20, true, ["red", "blue"]]';
    $array = json_decode($json_string);
    printf('Hello %s, You are %s years old.', $array[0], $array[1]);
    

    Use var_dump() to view the types and values of each property on the object we decoded above.

    // Dump our above $object to view how it was decoded
    var_dump($object);
    
    # Output: Note the variable 'types'
    class stdClass#2 (4) {
     ["name"] => string(4) "Jeff"
     ["age"] => int(20)
     ["active"] => bool(true)
     ["colors"] =>
       array(2) {
         [0] => string(3) "red"
         [1] => string(4) "blue"
       }
    }
    

    Note: The variable types in JSON were converted to their PHP equivalent.


    To return an associative array for JSON objects instead of returning an object, pass true as the second parameter to json_decode().

    $json_string = '{"name": "Jeff", "age": 20, "active": true, "colors": ["red", "blue"]}';
    $array = json_decode($json_string, true); // Note the second parameter
    var_dump($array);
    
    # Output: Note the array associative structure
    array(4) {
      ["name"] => string(4) "Jeff"
      ["age"] => int(20)
      ["active"] => bool(true)
      ["colors"] =>
      array(2) {
        [0] => string(3) "red"
        [1] => string(4) "blue"
      }
    }
    

    The second parameter ($assoc) has no effect if the variable to be returned is not an object.

    Note: If you use the $assoc parameter, you will lose the distinction between an empty array and an empty object. This means that running json_encode() on your decoded output again, will result in a different JSON structure.

    If the JSON string has a "depth" more than 512 elements (20 elements in versions older than 5.2.3, or 128 in version 5.2.3) in recursion, the function json_decode() returns NULL. In versions 5.3 or later, this limit can be controlled using the third parameter ($depth), as discussed below.


    According to the manual:

    PHP implements a superset of JSON as specified in the original » RFC 4627 - it will also encode and decode scalar types and NULL. RFC 4627 only supports these values when they are nested inside an array or an object. Although this superset is consistent with the expanded definition of "JSON text" in the newer » RFC 7159 (which aims to supersede RFC 4627) and » ECMA-404, this may cause interoperability issues with older JSON parsers that adhere strictly to RFC 4627 when encoding a single scalar value.

    This means, that, for example, a simple string will be considered to be a valid JSON object in PHP:

    $json = json_decode('"some string"', true);
    var_dump($json, json_last_error_msg());
    

    Output:

    string(11) "some string"
    string(8) "No error"
    

    But simple strings, not in an array or object, are not part of the RFC 4627 standard. As a result, such online checkers as JSLint, JSON Formatter & Validator (in RFC 4627 mode) will give you an error.

    There is a third $depth parameter for the depth of recursion (the default value is 512), which means the amount of nested objects inside the original object to be decoded.

    There is a fourth $options parameter. It currently accepts only one value, JSON_BIGINT_AS_STRING. The default behavior (which leaves off this option) is to cast large integers to floats instead of strings.

    Invalid non-lowercased variants of the true, false and null literals are no longer accepted as valid input.

    So this example:

    var_dump(json_decode('tRue'), json_last_error_msg());
    var_dump(json_decode('tRUe'), json_last_error_msg());
    var_dump(json_decode('tRUE'), json_last_error_msg());
    var_dump(json_decode('TRUe'), json_last_error_msg());
    var_dump(json_decode('TRUE'), json_last_error_msg());
    var_dump(json_decode('true'), json_last_error_msg());
    

    Before PHP 5.6:

    bool(true)
    string(8) "No error"
    bool(true)
    string(8) "No error"
    bool(true)
    string(8) "No error"
    bool(true)
    string(8) "No error"
    bool(true)
    string(8) "No error"
    bool(true)
    string(8) "No error"
    

    And after:

    NULL
    string(12) "Syntax error"
    NULL
    string(12) "Syntax error"
    NULL
    string(12) "Syntax error"
    NULL
    string(12) "Syntax error"
    NULL
    string(12) "Syntax error"
    bool(true)
    string(8) "No error"
    

    Similar behavior occurs for false and null.

    Note that json_decode() will return NULL if the string cannot be converted.

    $json = "{'name': 'Jeff', 'age': 20 }" ;  // invalid json 
    
    $person = json_decode($json);
    echo $person->name;    //  Notice: Trying to get property of non-object: returns null
    echo json_last_error();     
    #  4 (JSON_ERROR_SYNTAX)
    echo json_last_error_msg(); 
    #  unexpected character 
    

    It is not safe to rely only on the return value being NULL to detect errors. For example, if the JSON string contains nothing but "null", json_decode() will return null, even though no error occurred.

  • 70

    The json_encode function will convert a PHP array (or an object which implements JsonSerializable from PHP >= 5.4) to a JSON encoded string. It returns a JSON encoded string on success or FALSE on failure. The data must be in UTF-8.

    $array = ['name' => 'Jeff',
              'age' => 20,
              'active' => true,
              'colors' => ['red', 'blue']];
    

    Associative arrays are encoded as JSON Objects and non-associative arrays are encoded as JSON arrays.

    echo json_encode($array);
    
    #> {"name":"Jeff","age":20,"active":true,"colors":["red","blue"]}
    
    
    echo json_encode($array, JSON_PRETTY_PRINT);
    
    # Outputs a pretty printed JSON encoded string
    {
        "name": "Jeff",
        "age": 20,
        "active": true,
        "colors": [
            "red",
            "blue"
        ]
    }
    

    Note: The data types (string, integer, bool, array) are converted to their JSON equivalent.

    Note: When encoding an array, if the keys are not a continuous numeric sequence starting from 0, all keys are encoded as strings, and specified explicitly for each key-value pair.

    echo json_encode([0 => 'foo', 3 => 'bar']);
    
    #> { "0": "foo", "3": "bar" }
    
    echo json_encode([0 => 'foo', 1 => 'bar']);
    
    #> [ "foo", "bar" ]
    

    Bitmasks

    The second argument to json_encode is a bitmask which can be one or more of the following.

    As with any bitmask, they can be combined with the binary OR operator |.

    JSON_FORCE_OBJECT

    Forces the creation of an object instead of an array

    $array = ['Joel', 23, true, ['red', 'blue']];
    
    // Returns a JSON encoded array
    echo json_encode($array);
    #> ["Joel",23,true,["red","blue"]]
    
    // Returns a JSON encoded object
    echo json_encode($array, JSON_FORCE_OBJECT);
    #> {"0":"Joel","1":23,"2":true,"3":{"0":"red","1":"blue"}}
    
    // Combine bitmasks - force an object AND pretty print it
    echo json_encode($array, JSON_FORCE_OBJECT | JSON_PRETTY_PRINT);
    {
        "0": "Joel",
        "1": 23,
        "2": true,
        "3": {
            "0": "red",
            "1": "blue"
        }
    }
    

    JSON_HEX_APOS

    Ensures the apostrophe character ' is converted to \u0027

    $array = ["Singin' in Bahrain", "Charlie Wilson's War"];
    echo json_encode($array, JSON_HEX_APOS);
    #> ["Singin\u0027 in Bahrain","Charlie Wilson\u0027s War"]
    

    JSON_HEX_QUOT

    Ensures the quotation mark character " is converted to \u0022

    $array = ['"Mazdaratti Moms"', 'The "Man"churian Candidate'];
    echo json_encode($array, JSON_HEX_QUOT);
    #> ["\u0022Mazdaratti Moms\u0022","The \u0022Man\u0022churian Candidate"]
    

    JSON_NUMERIC_CHECK

    Ensures numeric strings are converted to integers. (available since PHP 5.3.3)

    $array = ['23452', 23452];
    
    echo json_encode($array);
    #> ["23452",23452]
    
    echo json_encode($array, JSON_NUMERIC_CHECK);
    #> [23452,23452]
    

    JSON_PRETTY_PRINT

    Makes the JSON more human readable

    $array = ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4];
    echo json_encode($array, JSON_PRETTY_PRINT);
    #>
    {
        "a": 1,
        "b": 2,
        "c": 3,
        "d": 4
    }
    

    JSON_UNESCAPED_SLASHES

    Includes unescaped / forward slashes in the output

    $array = ['filename' => 'example.txt', 'path' => '/full/path/to/file/'];
    
    echo json_encode($array);
    #> {"filename":"example.txt","path":"\/full\/path\/to\/file"}
    
    echo json_encode($array, JSON_UNESCAPED_SLASHES);
    #> {"filename":"example.txt","path":"/full/path/to/file"}
    

    JSON_UNESCAPED_UNICODE

    Includes UTF8-encoded characters in the output instead of \U-encoded strings

    $blues = ["english"=>"blue", "norwegian"=>"blå", "german"=>"blau"];
    
    echo json_encode($blues);
    #> {"english":"blue","norwegian":"bl\u00e5","german":"blau"}
    
    echo json_encode($blues, JSON_UNESCAPED_UNICODE);
    #> {"english":"blue","norwegian":"blå","german":"blau"}
    

    JSON_PRESERVE_ZERO_FRACTION

    Ensures that floats are always encoded as floats. (available since PHP 5.6.6)

    $array = [5.0, 5.5];
    echo json_encode($array);
    #> [5,5.5]
    
    echo json_encode($array, JSON_PRESERVE_ZERO_FRACTION);
    #> [5.0,5.5]
    
  • 40

    When json_encode or json_decode fails to parse the string provided, it will return false. PHP itself will not raise any errors or warnings when this happens, the onus is on the user to use the json_last_error() and json_last_error_msg() functions to check if an error occurred and act accordingly in your application (debug it, show an error message, etc.).

    The following example shows a common error when working with JSON, a failure to decode/encode a JSON string (due to the passing of a bad UTF-8 encoded string, for example).

    // An incorrectly formed JSON string
    $jsonString = json_encode("{'Bad JSON':\xB1\x31}");
    
    if (json_last_error() != JSON_ERROR_NONE) {
        printf("JSON Error: %s", json_last_error_msg());
    }
    
    #> JSON Error: Malformed UTF-8 characters, possibly incorrectly encoded
    

    json_last_error_msg

    json_last_error_msg() returns a human readable message of the last error that occurred when trying to encode/decode a string.

    • This function will always return a string, even if no error occurred.
      The default non-error string is No Error
    • It will return false if some other (unknown) error occurred
    • Careful when using this in loops, as json_last_error_msg will be overridden on each iteration.

    You should only use this function to get the message for display, not to test against in control statements.

    // Don't do this:
    if (json_last_error_msg()){} // always true (it's a string)
    if (json_last_error_msg() != "No Error"){} // Bad practice
    
    // Do this: (test the integer against one of the pre-defined constants)
    if (json_last_error() != JSON_ERROR_NONE) {
        // Use json_last_error_msg to display the message only, (not test against it)
        printf("JSON Error: %s", json_last_error_msg());
    }
    

    This function doesn't exist before PHP 5.5. Here is a polyfill implementation:

    if (!function_exists('json_last_error_msg')) {
        function json_last_error_msg() {
            static $ERRORS = array(
                JSON_ERROR_NONE => 'No error',
                JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
                JSON_ERROR_STATE_MISMATCH => 'State mismatch (invalid or malformed JSON)',
                JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded',
                JSON_ERROR_SYNTAX => 'Syntax error',
                JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded'
            );
    
            $error = json_last_error();
            return isset($ERRORS[$error]) ? $ERRORS[$error] : 'Unknown error';
        }
    }
    

    json_last_error

    json_last_error() returns an integer mapped to one of the pre-defined constants provided by PHP.

    ConstantMeaning
    JSON_ERROR_NONENo error has occurred
    JSON_ERROR_DEPTHThe maximum stack depth has been exceeded
    JSON_ERROR_STATE_MISMATCHInvalid or malformed JSON
    JSON_ERROR_CTRL_CHARControl character error, possibly incorrectly encoded
    JSON_ERROR_SYNTAXSyntax error (since PHP 5.3.3)
    JSON_ERROR_UTF8Malformed UTF-8 characters, possibly incorrectly encoded (since PHP 5.5.0)
    JSON_ERROR_RECURSIONOne or more recursive references in the value to be encoded
    JSON_ERROR_INF_OR_NANOne or more NAN or INF values in the value to be encoded
    JSON_ERROR_UNSUPPORTED_TYPEA value of a type that cannot be encoded was given
  • 8

    When you build REST API's, you may need to reduce the information of an object to be passed to the client application. For this purpose, this example illustrates how to use the JsonSerialiazble interface.

    In this example, the class User actually extends a DB model object of a hypotetical ORM.

    class User extends Model implements JsonSerializable {
        public $id;
        public $name;
        public $surname;
        public $username;
        public $password;
        public $email;
        public $date_created;
        public $date_edit;
        public $role;
        public $status;
    
        public function jsonSerialize() {
            return [
                'name' => $this->name,
                'surname' => $this->surname,
                'username' => $this->username
            ];
        }
    }
    

    Add JsonSerializable implementation to the class, by providing the jsonSerialize() method.

    public function jsonSerialize()
    

    Now in your application controller or script, when passing the object User to json_encode() you will get the return json encoded array of the jsonSerialize() method instead of the entire object.

    json_encode($User);
    

    Will return:

    {"name":"John", "surname":"Doe", "username" : "TestJson"}
    

    properties values example.

    This will both reduce the amount of data returned from a RESTful endpoint, and allow to exclude object properties from a json representation.


    Using Private and Protected Properties with json_encode()

    To avoid using JsonSerializable, it is also possible to use private or protected properties to hide class information from json_encode() output. The Class then does not need to implement \JsonSerializable.

    The json_encode() function will only encode public properties of a class into JSON.

    <?php
    
    class User {
        // private properties only within this class
        private $id;
        private $date_created;
        private $date_edit;
    
        // properties used in extended classes
        protected $password;
        protected $email;
        protected $role;
        protected $status;
    
        // share these properties with the end user        
        public $name;
        public $surname;
        public $username;
    
        // jsonSerialize() not needed here
    }        
    
    $theUser = new User();
    
    var_dump(json_encode($theUser));
    

    Output:

    string(44) "{"name":null,"surname":null,"username":null}"
    
  • 5

    by adding a header with content type as json :

    <?php
     $result = array('menu1' => 'home', 'menu2' => 'code php', 'menu3' => 'about');
    
    //return the json response :
    header('Content-Type: application/json');  // <-- header declaration
    echo json_encode($result, true);    // <--- encode
    exit();
    

    The header is there so your app can detect what data was returned and how it should handle it.
    note that : the content header is just information about type of returned data.

    if you are using utf8, you can use :

    header("Content-Type: application/json;charset=utf-8");
    

    Example jquery :

    $.ajax({
            url:'url_your_page_php_that_return_json'        
        }).done(function(data){
            console.table('json ',data);
            console.log('Menu1 : ', data.menu1);
        });
    
Please consider making a request to improve this example.

Syntax

  • string json_encode ( mixed $value [, int $options = 0 [, int $depth = 512 ]] )
  • mixed json_decode ( string $json [, bool $assoc = false [, int $depth = 512 [, int $options = 0 ]]] )

Parameters

ParameterDetails
json_encode-
valueThe value being encoded. Can be any type except a resource. All string data must be UTF-8 encoded.
optionsBitmask consisting of JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT, JSON_PRESERVE_ZERO_FRACTION, JSON_UNESCAPED_UNICODE, JSON_PARTIAL_OUTPUT_ON_ERROR. The behaviour of these constants is described on the JSON constants page.
depthSet the maximum depth. Must be greater than zero.
json_decode-
jsonThe json string being decoded. This function only works with UTF-8 encoded strings.
assocShould function return associative array instead of objects.
optionsBitmask of JSON decode options. Currently only JSON_BIGINT_AS_STRING is supported (default is to cast large integers as floats)

Remarks

  • json_decode handling of invalid JSON is very flaky, and it is very hard to reliably determine if the decoding succeeded, json_decode returns null for invalid input, even though null is also a perfectly valid object for JSON to decode to. To prevent such problems you should always call json_last_error every time you use it.
Still have a question about JSON? Ask Question

Topic Outline