Szukaj…
Wprowadzenie
JSON ( JavaScript Object Notation ) to niezależny od platformy i języka sposób serializacji obiektów na zwykły tekst. Ponieważ jest często używany w Internecie, podobnie jak PHP, istnieje podstawowe rozszerzenie do pracy z JSON w PHP.
Składnia
- ciąg json_encode (mieszana $ wartość [, int $ opcje = 0 [, int $ głębokość = 512]])
- mixed json_decode (ciąg $ json [, bool $ assoc = false [, int $ depth = 512 [, int $ options = 0]]])
Parametry
Parametr | Detale |
---|---|
json_encode | - |
wartość | Wartość jest kodowana. Może być dowolnego typu oprócz zasobu. Wszystkie dane ciągu muszą być zakodowane w UTF-8. |
opcje | Maska bitów składająca się z 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_ZER_PRES_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESS_PRESSIONE. Zachowanie tych stałych jest opisane na stronie stałych JSON . |
głębokość | Ustaw maksymalną głębokość. Musi być większy niż zero. |
json_decode | - |
json | Ciąg json jest dekodowany. Ta funkcja działa tylko z łańcuchami zakodowanymi w UTF-8. |
doc | Powinna funkcja zwracać tablicę asocjacyjną zamiast obiektów. |
opcje | Maska bitowa opcji dekodowania JSON. Obecnie obsługiwany jest tylko JSON_BIGINT_AS_STRING (domyślnie rzutuje duże liczby całkowite jako liczby zmiennoprzecinkowe) |
Uwagi
- Obsługa nieprawidłowego JSON przez json_decode jest bardzo niestabilna i bardzo trudno jest wiarygodnie ustalić, czy dekodowanie się powiodło, json_decode zwraca wartość null dla niepoprawnego wejścia, mimo że null jest również doskonale poprawnym obiektem do dekodowania przez JSON. Aby zapobiec takim problemom, zawsze powinieneś wywoływać json_last_error za każdym razem, gdy go używasz.
Dekodowanie ciągu JSON
Funkcja json_decode()
przyjmuje jako pierwszy parametr ciąg zakodowany w JSON i analizuje go w zmiennej PHP.
Zwykle json_decode()
zwróci obiekt \ stdClass, jeśli elementem najwyższego poziomu w obiekcie JSON jest słownik lub tablica indeksowana, jeśli obiekt JSON jest tablicą. Zwróci również wartości skalarne lub NULL
dla niektórych wartości skalarnych, takich jak proste łańcuchy, "true"
, "false"
i "null"
. Zwraca również NULL
dla każdego błędu.
// 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]);
Użyj var_dump()
aby wyświetlić typy i wartości każdej właściwości w obiekcie, który zdekodowaliśmy powyżej.
// Dump our above $object to view how it was decoded
var_dump($object);
Dane wyjściowe (zwróć uwagę na typy zmiennych):
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"
}
}
Uwaga: Typy zmiennych w JSON zostały przekonwertowane na ich odpowiedniki PHP.
Aby zwrócić tablicę asocjacyjną dla obiektów JSON zamiast zwracać obiekt, przekaż true
jako drugi parametr do 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);
Dane wyjściowe (zwróć uwagę na strukturę asocjacyjną tablicy):
array(4) {
["name"] => string(4) "Jeff"
["age"] => int(20)
["active"] => bool(true)
["colors"] =>
array(2) {
[0] => string(3) "red"
[1] => string(4) "blue"
}
}
Drugi parametr ( $assoc
) nie działa, jeśli zwracana zmienna nie jest obiektem.
Uwaga: Jeśli $assoc
parametru $assoc
, utracisz rozróżnienie między pustą tablicą a pustym obiektem. Oznacza to, że ponowne uruchomienie json_encode()
na zdekodowanym wyjściu spowoduje inną strukturę JSON.
Jeśli ciąg JSON ma „głębokość” większą niż 512 elementów ( 20 elementów w wersjach starszych niż 5.2.3 lub 128 w wersji 5.2.3 ) w rekurencji, funkcja json_decode()
zwraca NULL
. W wersjach 5.3 lub nowszych limit ten można kontrolować za pomocą trzeciego parametru ( $depth
), jak omówiono poniżej.
Zgodnie z instrukcją:
PHP implementuje nadzbiór JSON, jak określono w oryginalnym »RFC 4627 - będzie także kodować i dekodować typy skalarne i NULL. RFC 4627 obsługuje te wartości tylko wtedy, gdy są zagnieżdżone w tablicy lub obiekcie. Chociaż ten nadzbiór jest zgodny z rozszerzoną definicją „tekstu JSON” w nowszej wersji »RFC 7159 (która ma zastąpić RFC 4627) i » ECMA-404 , może to powodować problemy z interoperacyjnością ze starszymi parserami JSON, które ściśle przestrzegają RFC 4627, gdy kodowanie pojedynczej wartości skalarnej.
Oznacza to, że na przykład prosty ciąg zostanie uznany za prawidłowy obiekt JSON w PHP:
$json = json_decode('"some string"', true);
var_dump($json, json_last_error_msg());
Wynik:
string(11) "some string"
string(8) "No error"
Ale proste łańcuchy, nie w tablicy ani w obiekcie, nie są częścią standardu RFC 4627 . W rezultacie takie narzędzia do sprawdzania online, jak JSLint , JSON Formatter & Validator (w trybie RFC 4627) spowodują błąd.
Istnieje trzeci parametr $depth
dla głębokości rekurencji (wartość domyślna to 512
), co oznacza ilość zagnieżdżonych obiektów wewnątrz oryginalnego obiektu do odkodowania.
Istnieje czwarty parametr $options
. Obecnie akceptuje tylko jedną wartość, JSON_BIGINT_AS_STRING
. Domyślne zachowanie (które wyłącza tę opcję) polega na rzucaniu dużych liczb całkowitych na liczby zmiennoprzecinkowe zamiast łańcuchów.
Nieprawidłowe, nie zapisane małymi literami warianty literału true, false i null nie są już akceptowane jako prawidłowe dane wejściowe.
Więc ten przykład:
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());
Przed 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"
I po:
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"
Podobne zachowanie występuje w przypadku wartości false
i null
.
Zauważ, że json_decode()
zwróci NULL
jeśli ciąg nie może zostać przekonwertowany.
$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
Nie jest bezpiecznie polegać wyłącznie na wartości NULL
zwracanej w celu wykrycia błędów. Na przykład, jeśli ciąg JSON nie zawiera nic oprócz "null"
, json_decode()
zwróci null
, mimo że nie wystąpił błąd.
Kodowanie ciągu JSON
Funkcja json_encode
przekształci tablicę PHP (lub, od PHP 5.4, obiekt, który implementuje interfejs JsonSerializable
) na ciąg zakodowany w JSON. Zwraca ciąg zakodowany w JSON w przypadku sukcesu lub FALSE w przypadku niepowodzenia.
$array = [
'name' => 'Jeff',
'age' => 20,
'active' => true,
'colors' => ['red', 'blue'],
'values' => [0=>'foo', 3=>'bar'],
];
Podczas kodowania ciąg typów danych PHP, liczba całkowita i wartość logiczna są konwertowane na ich odpowiednik JSON. Tablice asocjacyjne są kodowane jako obiekty JSON, a - gdy są wywoływane z domyślnymi argumentami - tablice indeksowane są kodowane jako tablice JSON. (Chyba że klucze tablicy nie są ciągłą sekwencją numeryczną rozpoczynającą się od 0, w którym to przypadku tablica zostanie zakodowana jako obiekt JSON.)
echo json_encode($array);
Wynik:
{"name":"Jeff","age":20,"active":true,"colors":["red","blue"],"values":{"0":"foo","3":"bar"}}
Argumenty
Od PHP 5.3 drugim argumentem do json_encode
jest json_encode
bitowa, która może być jedną lub więcej z poniższych.
Podobnie jak w przypadku każdej maski bitowej, można je łączyć z binarnym operatorem OR |
.
JSON_FORCE_OBJECT
Wymusza utworzenie obiektu zamiast tablicy
$array = ['Joel', 23, true, ['red', 'blue']];
echo json_encode($array);
echo json_encode($array, JSON_FORCE_OBJECT);
Wynik:
["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
Zapewnia następujące konwersje podczas kodowania:
Stały | Wejście | Wynik |
---|---|---|
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);
Wynik:
{"tag":"<>","amp":"&","apos":"'","quot":"\""}
{"tag":"\u003C\u003E","amp":"\u0026","apos":"\u0027","quot":"\u0022"}
JSON_NUMERIC_CHECK
Zapewnia, że ciągi liczbowe są konwertowane na liczby całkowite.
$array = ['23452', 23452];
echo json_encode($array);
echo json_encode($array, JSON_NUMERIC_CHECK);
Wynik:
["23452",23452]
[23452,23452]
JSON_PRETTY_PRINT
Sprawia, że JSON jest łatwo czytelny
$array = ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4];
echo json_encode($array);
echo json_encode($array, JSON_PRETTY_PRINT);
Wynik:
{"a":1,"b":2,"c":3,"d":4}
{
"a": 1,
"b": 2,
"c": 3,
"d": 4
}
JSON_UNESCAPED_SLASHES
Obejmuje ukośniki nieokreślone /
przodu na wyjściu
$array = ['filename' => 'example.txt', 'path' => '/full/path/to/file/'];
echo json_encode($array);
echo json_encode($array, JSON_UNESCAPED_SLASHES);
Wynik:
{"filename":"example.txt","path":"\/full\/path\/to\/file"}
{"filename":"example.txt","path":"/full/path/to/file"}
JSON_UNESCAPED_UNICODE
Zawiera w kodzie wyjściowym znaki zakodowane w UTF8 zamiast ciągów zakodowanych w formacie \u
$blues = ["english"=>"blue", "norwegian"=>"blå", "german"=>"blau"];
echo json_encode($blues);
echo json_encode($blues, JSON_UNESCAPED_UNICODE);
Wynik:
{"english":"blue","norwegian":"bl\u00e5","german":"blau"}
{"english":"blue","norwegian":"blå","german":"blau"}
JSON_PARTIAL_OUTPUT_ON_ERROR
Zezwala na kontynuowanie kodowania, jeśli napotkane zostaną pewne wartości niekodowalne.
$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);
Wynik:
{"file":null,"name":"foo.txt"}
JSON_PRESERVE_ZERO_FRACTION
Zapewnia, że zmiennoprzecinkowe są zawsze kodowane jako zmiennoprzecinkowe.
$array = [5.0, 5.5];
echo json_encode($array);
echo json_encode($array, JSON_PRESERVE_ZERO_FRACTION);
Wynik:
[5,5.5]
[5.0,5.5]
JSON_UNESCAPED_LINE_TERMINATORS
W połączeniu z JSON_UNESCAPED_UNICODE
zachowanie starszych wersji PHP i nie ucieka przed znakami U + 2028 LINE SEPARATOR i U + 2029 SEPARATOR PARAGRAPH. Chociaż są one poprawne w JSON, te znaki nie są poprawne w JavaScript, więc domyślne zachowanie JSON_UNESCAPED_UNICODE
zostało zmienione w wersji 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);
Wynik:
{"line":"\u2028","paragraph":"\u2029"}
{"line":"
","paragraph":"
"}
Debugowanie błędów JSON
Kiedy json_encode
lub json_decode
nie trafia do analizowania ciąg dostarczone, zwróci false
. Sam PHP nie będzie generował żadnych błędów ani ostrzeżeń, gdy to się stanie, na użytkowniku spoczywa obowiązek użycia funkcji json_last_error () i json_last_error_msg () w celu sprawdzenia, czy wystąpił błąd i działania odpowiednio w aplikacji (debuguj go, pokaż komunikat o błędzie itp.).
Poniższy przykład pokazuje typowy błąd podczas pracy z JSON, błąd dekodowania / kodowania łańcucha JSON (na przykład z powodu przekazania nieprawidłowego łańcucha zakodowanego UTF-8) .
// 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()
zwraca czytelny dla człowieka komunikat o ostatnim błędzie, który wystąpił podczas próby zakodowania / odkodowania łańcucha.
- Ta funkcja zawsze zwraca ciąg znaków , nawet jeśli nie wystąpił błąd.
Ciąg domyślny zakaz błęduNo Error
- Zwróci
false
jeśli wystąpi inny (nieznany) błąd - Ostrożnie, gdy używasz tego w pętlach, ponieważ json_last_error_msg zostanie zastąpiony przy każdej iteracji.
Tej funkcji należy używać tylko do otrzymania komunikatu do wyświetlenia, a nie do testowania w instrukcjach sterujących.
// 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());
}
Ta funkcja nie istnieje przed PHP 5.5. Oto implementacja polifill:
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()
zwraca liczbę całkowitą odwzorowaną na jedną ze wstępnie zdefiniowanych stałych dostarczonych przez PHP.
Stały | Znaczenie |
---|---|
JSON_ERROR_NONE | Nie wystąpił błąd |
JSON_ERROR_DEPTH | Maksymalna głębokość stosu została przekroczona |
JSON_ERROR_STATE_MISMATCH | Niepoprawny lub zniekształcony JSON |
JSON_ERROR_CTRL_CHAR | Błąd znaku kontrolnego, być może niepoprawnie zakodowany |
JSON_ERROR_SYNTAX | Błąd składniowy (od PHP 5.3.3) |
JSON_ERROR_UTF8 | Zniekształcone znaki UTF-8, być może niepoprawnie zakodowane (od PHP 5.5.0) |
JSON_ERROR_RECURSION | Co najmniej jedno odwołanie rekurencyjne w wartości do zakodowania |
JSON_ERROR_INF_OR_NAN | Jedna lub więcej wartości NAN lub INF w wartości do zakodowania |
JSON_ERROR_UNSUPPORTED_TYPE | Podano wartość typu, którego nie można zakodować |
Korzystanie z JsonSerializable w obiekcie
Podczas tworzenia interfejsów API REST może być konieczne zmniejszenie informacji o obiekcie, który ma zostać przekazany do aplikacji klienckiej. W tym celu w tym przykładzie pokazano, jak korzystać z interfejsu JsonSerialiazble
.
W tym przykładzie klasa User
faktycznie rozszerza obiekt modelu DB hipotetycznej 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
];
}
}
Dodaj implementację JsonSerializable
do klasy, udostępniając jsonSerialize()
.
public function jsonSerialize()
Teraz w twoim kontrolerze aplikacji lub skrypcie, przekazując obiekt User do json_encode()
, otrzymasz całą tablicę zakodowaną w json metody jsonSerialize()
zamiast całego obiektu.
json_encode($User);
Wróci:
{"name":"John", "surname":"Doe", "username" : "TestJson"}
przykład wartości właściwości.
Zmniejszy to zarówno ilość danych zwracanych z punktu końcowego RESTful, jak i pozwoli wykluczyć właściwości obiektu z reprezentacji json.
Korzystanie z właściwości prywatnych i chronionych za pomocą json_encode()
Aby uniknąć używania JsonSerializable, możliwe jest również użycie właściwości prywatnych lub chronionych w celu ukrycia informacji o klasie przed wyjściem json_encode()
. Klasa nie musi zatem implementować \ JsonSerializable.
Funkcja json_encode () będzie kodować tylko publiczne właściwości klasy w 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));
Wynik:
string(44) "{"name":null,"surname":null,"username":null}"
Nagłówek Json i zwrócona odpowiedź
Dodając nagłówek z typem zawartości jako 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();
Nagłówek jest tam, aby Twoja aplikacja mogła wykryć, które dane zostały zwrócone i jak powinny je obsługiwać.
Uwaga: nagłówek treści to tylko informacja o rodzaju zwracanych danych.
Jeśli używasz UTF-8, możesz użyć:
header("Content-Type: application/json;charset=utf-8");
Przykład jQuery:
$.ajax({
url:'url_your_page_php_that_return_json'
}).done(function(data){
console.table('json ',data);
console.log('Menu1 : ', data.menu1);
});