To decode JSON Text, PHP has the json_decode() function:
$ php -n --rf json_decode
Function [ <internal:json> function json_decode ] {
- Parameters [4] {
Parameter #0 [ <required> string $json ]
Parameter #1 [ <optional> ?bool $associative = null ]
Parameter #2 [ <optional> int $depth = 512 ]
Parameter #3 [ <optional> int $flags = 0 ]
}
- Return [ mixed ]
}
In case you are using an older PHP version, it might not exist without loading a PHP extension:
$ php -n --rf json_decode
Exception: Function json_decode() does not exist
The JSON Text needs to be passed on the first parameter named json as a scalar type string value.
The resulting data can then be accessed on the functions return value.
My answer relates to this standard JSON text decoder in PHP, there are other decoders available which may yield different runtime behaviour which is not possible to cover in this answer. Nevertheless, sometimes I provide reference to other and related PHP extensions in this answer.
If a JSON text does not represent valid JSON for PHP, the json_validate() function returns false. Its properties are comparable to the decoding function, both for its availability and usage. Therefore I consider it part of the PHP JSON decoder (or PHP as a JSON parser) and specifically mention it as "valid JSON for PHP".
Given a JSON text, when it is provided as a string and valid JSON for PHP, then the decoding function will return the data in the PHP representation, a value with the union type of object|array|string|float|int|bool|null.
The data can then be stored in a variable by assigning the functions return value to it.
To make the decode function never returning on invalid JSON for PHP, the global constant JSON_THROW_ON_ERROR can be added to the flags scalar type integer value on the fourth parameter named flags.
Sections 4 and 8 of RFC8259 already identify specific situations that may conform to the grammar for JSON texts but are not interoperable uses of JSON, as they may cause unpredictable behavior.
JSON object properties are constrained by PHP, only a subset of JSON text can be decoded: A PHP object does not have same-named properties. The PHP JSON decoder will therefore create the JSON objects' member variable when decoded the first time and assign its value. The next time it will assign the value to the same member variable again, overwriting its previous value. This behaviour cannot be changed with a flag (fourth parameter of the decode function, see the first listing).
Another constraint is that not all JSON object property names are acceptable ones of PHP objects. If the JSON Text contains such property names that are not portable for PHP object member variable names, the second parameter of the decode function should be set to the scalar type boolean value true.
PHP then decodes all JSON objects as associative arrays which has wider compatibility as PHP array keys are less constrained than PHP object property (member variable) names.
This enhances the accessibility of the encoded JSON object members with the PHP JSON decoder but has the representation invariant that both empty arrays (lists) and empty objects (entities) collapse into the empty array and can't be distinguished from each other in the PHP representation any longer.
As long as no empty objects are expected or the decoding is done only to validate property names, this distinguishing may not be of concern, but this depends on how the return value of the PHP JSON decode function is being used.
The PHP JSON decoders' input string is binary (octets), and the only supported text encoding UTF-8 RFC3629. Previous specifications of JSON have not required the use of UTF-8 when transmitting JSON text. However, the JSON-based PHP implementation has chosen, as did many other JSON decoding libraries, to use the UTF-8 encoding, to the extent that it is the only encoding that achieves interoperability without relying on another PHP extension. The PHP JSON decoder treats the UTF-8 byte-order mark (BOM) as an error. This behaviour might be noteworthy and it cannot be changed with a flag.
Section 8.3 of RFC8259 identifies member names and string values that contain bit sequences that cannot encode Unicode characters; for example, "\uDEAD" (a single unpaired UTF-16 surrogate). Albeit the augmented Backus–Naur form (ABNF) of the JSON specification allows these member names, the behaviour of software that receives JSON text containing such values has already been identified as unpredictable (ebd.). The PHP JSON decoder yields these as JSON errors more predictably. As the PHP JSON decoder does not furthermore add constraints on names (and/or associated keys), this is both the baseline and the ceiling. The PHP JSON decoder has no further options, neither as a naming profile, schema validation or a reviver callback for the JSON decoding function.
Section 9 of RFC8259 describes a JSON parser. In hindsight of the PHP JSON decode function, it accepts all texts that conform to the JSON grammar and transforms it into another representation. The PHP representation is the returned value of the union type (see above) or by throwing a JsonException (ebd.). As a JSON parser may accept non-JSON forms or extensions, the PHP JSON decoder function does accept such texts, but they give a positive JSON error result as any other JSON text that is not considered valid JSON for PHP, folding to a null return value or throwing by the JSON_THROW_ON_ERROR flag in the error case.
JSON extensions like JSON5 are only available via other PHP extensions, for example SQLite —also via the PHP Data Objects (PDO).
The PHP JSON decoder sets limits on the size of texts that it accepts. This can be configured in PHP directives for the size of input variables and overall memory limit. Furthermore a PHP configuration is constrained at runtime by how much memory the operating system or SAPI host provides to the PHP process.
The PHP JSON decoder has a default limit on the maximum depth of nesting —512— which can be controlled by the third parameter named depth, a scalar type integer value —throws ValueError unless greater than 0.
Example 1. Decoding JSON Text Input in PHP
Decoding the JSON text of the question as PHP input with the PHP JSON decode function and accessing the data.
$data = json_decode(
json : file_get_contents('php://input'),
associative: null,
depth : 4,
flags : JSON_THROW_ON_ERROR,
);
Each date in the data can be accessed by their names (variables) and keys (arrays/lists) within the potentially compound structure of the data interchanged via the JSON text in the decoded PHP representation of the data.
Names have a string representation in PHP and keys an integer, float or string representation.
For JSON arrays, the PHP decoder uses integer keys starting from zero until the count surpasses PHP_INT_MAX —a global constant type integer with the maximum positive integer value the PHP build is capable of—, then changing to float for the value of the key then implicitly converting to the integer type, an operation with precision-loss. This representation invariant is commonly ignored in PHP JSON decoding, because such arrays (as lists) are not fitting the short running request/response cycles during data-interchange for time and space. The size of such lists however cannot by limited with a parameter of the JSON decode function.
Consult the hosts PHP configuration for the value ranges of the numeric data types, as the PHP representation is accordingly for numeric values in the JSON text. The fourth parameter named flags of the PHP JSON decode function allows to control the behaviour of the parsing also in this regard, the JSON_BIGINT_AS_STRING flag directs the PHP JSON parser to decode large integers as their original string value —but not for array indexes. (ref.)
Names in their string representation can be made expressive by quoting the string literal in curly brackets ({…}). This is not a requirement thought as long as the identifier does not conflict with the PHP language internal syntax rules. Conflicts may arise on a reserved word of language and/or symbols of syntactic constructs, e.g. the curly brackets just mentioned or PHP token separating white-space sequences, PHP comment symbols, or sometimes even non-string literals. E.g., null is a valid name, 0 isn't. Expressing names by their string literals as in {'null'} and {'0'} unambiguously identifies them as names in the PHP language.
Variable names are prefixed with the dollar sign ($). Object variable names are prefixed with the hyphen-minus (-) immediately followed by the greater-than sign (>) forming a rightwards arrow → (->.)
Keys for both their integer and string representation are quoted in square brackets ([…]).
In the past, it was also possible to use curly brackets for array keys, that probably was useful for Perl linguists. This is now gone, enforcing more semantic clarity in the language.
As the two structured kinds of values, JSON object and JSON array, are decoded by the PHP JSON decode function into one of their two counter-parts, PHP object and PHP array, the data in the JSON text of the question can be accessed as a whole (variable) or as a subcomponent (array member/ object variable) finally reaching each date with the PHP expression naming —or pointing to— it.
Table 1. Accessing the Example Data decoded from JSON Text in PHP
| Expression |
Date or Data |
${'data'}->{'type'} |
'donut' |
${'data'}->{'name'} |
'Cake' |
${'data'}->{'toppings'}[0]->{'id'} |
'5002' |
${'data'}->{'toppings'}[0]->{'type'} |
'Glazed' |
${'data'}->{'toppings'}[0] |
stdClass |
${'data'}->{'toppings'}[1]->{'id'} |
'5006' |
${'data'}->{'toppings'}[1]->{'type'} |
'Chocolate with Sprinkles' |
${'data'}->{'toppings'}[1] |
stdClass |
${'data'}->{'toppings'}[2]->{'id'} |
'5004' |
${'data'}->{'toppings'}[2]->{'type'} |
'Maple' |
${'data'}->{'toppings'}[2] |
stdClass |
${'data'}->{'toppings'} |
array |
${'data'} |
stdClass |
And as previously outlined or per the Manual, or here.