Ricerca…


introduzione

JSON ( JavaScript Object Notation ) è un modo indipendente dalla piattaforma e dal linguaggio per serializzare gli oggetti in testo semplice. Poiché viene spesso utilizzato su Web e così anche per PHP, esiste un'estensione di base per lavorare con JSON in PHP.

Sintassi

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

Parametri

Parametro Dettagli
json_encode -
valore Il valore codificato. Può essere di qualsiasi tipo tranne una risorsa. Tutti i dati di stringa devono essere codificati in UTF-8.
opzioni Bitmask costituito da 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. Il comportamento di queste costanti è descritto nella pagina delle costanti JSON .
profondità Imposta la profondità massima. Deve essere maggiore di zero.
json_decode -
jSON La stringa json viene decodificata. Questa funzione funziona solo con stringhe con codifica UTF-8.
assoc Dovrebbe funzionare restituire array associativo anziché oggetti.
opzioni Bitmask delle opzioni di decodifica JSON. Attualmente è supportato solo JSON_BIGINT_AS_STRING (l'impostazione predefinita è il cast di interi grandi come float)

Osservazioni

  • la gestione json_decode di JSON non valido è molto instabile, ed è molto difficile determinare in modo affidabile se la decodifica ha avuto successo, json_decode restituisce null per input non validi, anche se null è anche un oggetto perfettamente valido per JSON da decodificare. Per evitare tali problemi, devi sempre chiamare json_last_error ogni volta che lo usi.

Decodifica una stringa JSON

La funzione json_decode() accetta una stringa con codifica JSON come suo primo parametro e la analizza in una variabile PHP.

Normalmente, json_decode() restituirà un oggetto di \ stdClass se l'elemento di livello superiore nell'oggetto JSON è un dizionario o un array indicizzato se l'oggetto JSON è un array. Restituirà anche valori scalari o NULL per determinati valori scalari, come stringhe semplici, "true" , "false" e "null" . Restituisce anche NULL su qualsiasi errore.

// 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]);

Utilizzare var_dump() per visualizzare i tipi e i valori di ogni proprietà sull'oggetto decodificato in precedenza.

// Dump our above $object to view how it was decoded
var_dump($object);

Uscita (notare i tipi di variabile):

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"
   }
}

Nota: i tipi di variabile in JSON sono stati convertiti nel loro equivalente PHP.


Per restituire un array associativo per oggetti JSON invece di restituire un oggetto, passare true come secondo parametro a 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 (notare la struttura associativa dell'array):

array(4) {
  ["name"] => string(4) "Jeff"
  ["age"] => int(20)
  ["active"] => bool(true)
  ["colors"] =>
  array(2) {
    [0] => string(3) "red"
    [1] => string(4) "blue"
  }
}

Il secondo parametro ( $assoc ) non ha alcun effetto se la variabile da restituire non è un oggetto.

Nota: se si utilizza il parametro $assoc , si perde la distinzione tra una matrice vuota e un oggetto vuoto. Ciò significa che l'esecuzione di json_encode() sull'output decodificato risulterà in una diversa struttura JSON.

Se la stringa JSON ha una "profondità" superiore a 512 elementi ( 20 elementi nelle versioni precedenti alla 5.2.3 o 128 nella versione 5.2.3 ) in ricorsione, la funzione json_decode() restituisce NULL . Nelle versioni 5.3 o successive, questo limite può essere controllato usando il terzo parametro ( $depth ), come discusso di seguito.


Secondo il manuale:

PHP implementa un superset di JSON come specificato nell'originale »RFC 4627 - codificherà e decodificherà anche i tipi scalari e NULL. RFC 4627 supporta solo questi valori quando sono nidificati all'interno di un array o di un oggetto. Sebbene questo superset sia coerente con la definizione ampliata di "testo JSON" nel nuovo »RFC 7159 (che mira a sostituire RFC 4627) e » ECMA-404 , ciò potrebbe causare problemi di interoperabilità con parser JSON più vecchi che aderiscono strettamente a RFC 4627 quando codifica di un singolo valore scalare.

Ciò significa che, ad esempio, una stringa semplice sarà considerata come un oggetto JSON valido in PHP:

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

Produzione:

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

Ma le stringhe semplici, non in un array o in un oggetto, non fanno parte dello standard RFC 4627 . Di conseguenza, tali controllori online come JSLint , JSON Formatter & Validator (in modalità RFC 4627) ti daranno un errore.

Esiste un terzo parametro $depth per la profondità della ricorsione (il valore predefinito è 512 ), che significa la quantità di oggetti nidificati all'interno dell'oggetto originale da decodificare.

C'è un quarto parametro $options . Attualmente accetta solo un valore, JSON_BIGINT_AS_STRING . Il comportamento predefinito (che abbandona questa opzione) consiste nel trasmettere interi grandi a float anziché stringhe.

Le varianti non minuscole non valide dei letterali true, false e null non sono più accettate come input valido.

Quindi questo esempio:

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());

Prima di 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"

E dopo:

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"

Comportamento simile si verifica per false e null .

Si noti che json_decode() restituirà NULL se la stringa non può essere convertita.

$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 

Non è sicuro affidarsi solo al valore restituito NULL per rilevare errori. Ad esempio, se la stringa JSON non contiene altro che "null" , json_decode() restituirà null , anche se non si è verificato alcun errore.

Codifica di una stringa JSON

La funzione json_encode convertirà un array PHP (o, dal momento che PHP 5.4, un oggetto che implementa l'interfaccia JsonSerializable ) in una stringa con codifica JSON. Restituisce una stringa con codifica JSON in caso di successo o FALSE in caso di errore.

$array = [
    'name' => 'Jeff',
    'age' => 20,
    'active' => true,
    'colors' => ['red', 'blue'],
    'values' => [0=>'foo', 3=>'bar'],
];

Durante la codifica, i tipi di dati PHP string, integer e boolean vengono convertiti nel loro equivalente JSON. Gli array associativi sono codificati come oggetti JSON e, quando vengono chiamati con argomenti predefiniti, gli array indicizzati sono codificati come array JSON. (A meno che le chiavi dell'array non siano una sequenza numerica continua a partire da 0, nel qual caso l'array sarà codificato come oggetto JSON.)

echo json_encode($array);

Produzione:

{"name":"Jeff","age":20,"active":true,"colors":["red","blue"],"values":{"0":"foo","3":"bar"}}

argomenti

Dal PHP 5.3, il secondo argomento di json_encode è una maschera di bit che può essere uno o più dei seguenti.

Come con qualsiasi maschera di bit, possono essere combinati con l'operatore OR binario | .

PHP 5.x 5.3

JSON_FORCE_OBJECT

Forza la creazione di un oggetto invece di un array

$array = ['Joel', 23, true, ['red', 'blue']];
echo json_encode($array);
echo json_encode($array, JSON_FORCE_OBJECT);

Produzione:

["Joel",23,true,["red","blue"]]
{"0":"Joel","1":23,"2":true,"3":{"0":"red","1":"blue"}}

JSON_HEX_TAG , JSON_HEX_AMP , JSON_HEX_APOS , JSON_HEX_QUOT

Assicura le seguenti conversioni durante la codifica:

Costante Ingresso Produzione
JSON_HEX_TAG < \u003C
JSON_HEX_TAG > \u003E
JSON_HEX_AMP & \u0026
JSON_HEX_APOS ' \u0027
JSON_HEX_QUOT " \u0022
$array = ["tag"=>"<>", "amp"=>"&", "apos"=>"'", "quot"=>"\""];
echo json_encode($array);
echo json_encode($array, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);

Produzione:

{"tag":"<>","amp":"&","apos":"'","quot":"\""}
{"tag":"\u003C\u003E","amp":"\u0026","apos":"\u0027","quot":"\u0022"}
PHP 5.x 5.3

JSON_NUMERIC_CHECK

Garantisce che le stringhe numeriche vengano convertite in numeri interi.

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

Produzione:

["23452",23452]    
[23452,23452]
PHP 5.x 5.4

JSON_PRETTY_PRINT

Rende facilmente leggibile il JSON

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

Produzione:

{"a":1,"b":2,"c":3,"d":4}
{
    "a": 1,
    "b": 2,
    "c": 3,
    "d": 4
}

JSON_UNESCAPED_SLASHES

Include barre senza escape / avanti nell'output

$array = ['filename' => 'example.txt', 'path' => '/full/path/to/file/'];
echo json_encode($array);
echo json_encode($array, JSON_UNESCAPED_SLASHES);

Produzione:

{"filename":"example.txt","path":"\/full\/path\/to\/file"}
{"filename":"example.txt","path":"/full/path/to/file"}

JSON_UNESCAPED_UNICODE

Include i caratteri con codifica UTF8 nell'output anziché le stringhe con codifica \u

$blues = ["english"=>"blue", "norwegian"=>"blå", "german"=>"blau"];
echo json_encode($blues);
echo json_encode($blues, JSON_UNESCAPED_UNICODE);

Produzione:

{"english":"blue","norwegian":"bl\u00e5","german":"blau"}
{"english":"blue","norwegian":"blå","german":"blau"}
PHP 5.x 5.5

JSON_PARTIAL_OUTPUT_ON_ERROR

Permette alla codifica di continuare se si incontrano alcuni valori non convertibili.

$fp = fopen("foo.txt", "r");
$array = ["file"=>$fp, "name"=>"foo.txt"];
echo json_encode($array); // no output
echo json_encode($array, JSON_PARTIAL_OUTPUT_ON_ERROR);

Produzione:

{"file":null,"name":"foo.txt"}
PHP 5.x 5.6

JSON_PRESERVE_ZERO_FRACTION

Garantisce che i float siano sempre codificati come float.

$array = [5.0, 5.5];
echo json_encode($array);
echo json_encode($array, JSON_PRESERVE_ZERO_FRACTION);

Produzione:

[5,5.5]
[5.0,5.5]
PHP 7.x 7.1

JSON_UNESCAPED_LINE_TERMINATORS

Se utilizzato con JSON_UNESCAPED_UNICODE , ripristina il comportamento delle versioni precedenti di PHP e non sfugge ai caratteri U + 2028 LINE SEPARATOR e U + 2029 PARAGRAPH SEPARATOR. Sebbene validi in JSON, questi caratteri non sono validi in JavaScript, quindi il comportamento predefinito di JSON_UNESCAPED_UNICODE stato modificato nella versione 7.1.

$array = ["line"=>"\xe2\x80\xa8", "paragraph"=>"\xe2\x80\xa9"];
echo json_encode($array, JSON_UNESCAPED_UNICODE);
echo json_encode($array, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_LINE_TERMINATORS);

Produzione:

{"line":"\u2028","paragraph":"\u2029"}
{"line":"
","paragraph":"
"}

Debug degli errori JSON

Quando json_encode o json_decode non riesce ad analizzare la stringa fornita, restituirà false . PHP non genererà alcun errore o avvertimento quando ciò accadrà, l'utente dovrà utilizzare le funzioni json_last_error () e json_last_error_msg () per verificare se si è verificato un errore e agire di conseguenza nella propria applicazione (eseguirne il debug, mostrare un messaggio di errore , eccetera.).

L'esempio seguente mostra un errore comune quando si lavora con JSON, un errore di decodifica / codifica di una stringa JSON (a causa del passaggio di una stringa errata con codifica UTF-8, ad esempio) .

// 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() restituisce un messaggio leggibile dall'ultimo errore che si è verificato durante il tentativo di codificare / decodificare una stringa.

  • Questa funzione restituirà sempre una stringa , anche se non si è verificato alcun errore.
    La stringa predefinita non di errore è No Error
  • Restituirà false se si è verificato un altro errore (sconosciuto)
  • Attento quando si usa questo nei loop, poiché json_last_error_msg verrà sovrascritto su ogni iterazione.

Dovresti usare questa funzione solo per visualizzare il messaggio, non per testarlo nelle istruzioni di controllo.

// 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());
}

Questa funzione non esiste prima di PHP 5.5. Ecco una implementazione di polyfill:

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() restituisce un intero mappato a una delle costanti predefinite fornite da PHP.

Costante Senso
JSON_ERROR_NONE Nessun errore si è verificato
JSON_ERROR_DEPTH La profondità massima dello stack è stata superata
JSON_ERROR_STATE_MISMATCH JSON non valido o non valido
JSON_ERROR_CTRL_CHAR Controlla l'errore del carattere, eventualmente codificato in modo errato
JSON_ERROR_SYNTAX Errore di sintassi (da PHP 5.3.3)
JSON_ERROR_UTF8 Caratteri UTF-8 non validi , eventualmente codificati in modo errato (dal PHP 5.5.0)
JSON_ERROR_RECURSION Uno o più riferimenti ricorsivi nel valore da codificare
JSON_ERROR_INF_OR_NAN Uno o più valori NAN o INF nel valore da codificare
JSON_ERROR_UNSUPPORTED_TYPE È stato fornito un valore di un tipo che non può essere codificato

Usare JsonSerializable in un oggetto

PHP 5.x 5.4

Quando si creano API REST, potrebbe essere necessario ridurre le informazioni di un oggetto da passare all'applicazione client. A tale scopo, questo esempio illustra come utilizzare l'interfaccia JsonSerialiazble .

In questo esempio, la classe User estende effettivamente un oggetto modello DB di un ORM ipotetico.

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
        ];
    }
}

Aggiungi JsonSerializable implementazione JsonSerializable alla classe, fornendo il metodo jsonSerialize() .

public function jsonSerialize()

Ora nel controller dell'applicazione o nello script, quando si passa l'oggetto User a json_encode() si otterrà la matrice restituita con json del metodo jsonSerialize() invece dell'intero oggetto.

json_encode($User);

Tornerà:

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

esempio di valori di proprietà.

Ciò riduce la quantità di dati restituiti da un endpoint RESTful e consente di escludere le proprietà dell'oggetto da una rappresentazione json.


Utilizzo di proprietà private e protette con json_encode()

Per evitare l'uso di JsonSerializable, è anche possibile utilizzare proprietà private o protette per nascondere le informazioni sulla classe json_encode() di json_encode() . La classe quindi non ha bisogno di implementare \ JsonSerializable.

La funzione json_encode () codifica solo le proprietà pubbliche di una classe in 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));

Produzione:

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

Header json e la risposta restituita

Aggiungendo un'intestazione con tipo di contenuto come 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();

L'intestazione è lì così la tua app può rilevare quali dati sono stati restituiti e come dovrebbe gestirli.
Nota: l'intestazione del contenuto è solo informazioni sul tipo di dati restituiti.

Se si utilizza UTF-8, è possibile utilizzare:

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

Esempio jQuery:

$.ajax({
        url:'url_your_page_php_that_return_json'        
    }).done(function(data){
        console.table('json ',data);
        console.log('Menu1 : ', data.menu1);
    });


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow