Поиск…
Вступление
JSON ( JavaScript Object Notation ) - это независимый от платформы и язык способ сериализации объектов в открытый текст. Поскольку он часто используется в Интернете, а также PHP, существует базовое расширение для работы с JSON в PHP.
Синтаксис
- string json_encode (mixed $ value [, int $ options = 0 [, int $ depth = 512]])
- смешанный json_decode (строка $ json [, bool $ assoc = false [, int $ depth = 512 [, int $ options = 0]]])
параметры
параметр | подробности |
---|---|
json_encode | - |
значение | Кодирование значения. Может быть любым типом, кроме ресурса. Все строковые данные должны кодироваться в кодировке UTF-8. |
опции | Бит-маска, состоящая из 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. Поведение этих констант описано на странице констант JSON . |
глубина | Установите максимальную глубину. Должно быть больше нуля. |
json_decode | - |
JSON | Строка json декодируется. Эта функция работает только с закодированными строками UTF-8. |
ассоциативный | Функция должна возвращать ассоциативный массив вместо объектов. |
опции | Бит-маска параметров декодирования JSON. В настоящее время поддерживается только JSON_BIGINT_AS_STRING (по умолчанию используется большое число целых чисел в виде поплавков) |
замечания
- Обработка json_decode недопустимого JSON очень шелушащая, и очень сложно надежно определить, удалось ли декодировать, json_decode возвращает значение null для недопустимого ввода, хотя null также является вполне допустимым объектом для JSON для декодирования. Чтобы предотвратить такие проблемы, вы всегда должны вызывать json_last_error каждый раз, когда используете его.
Декодирование строки JSON
Функция json_decode()
принимает JSON-кодированную строку в качестве своего первого параметра и анализирует ее в переменной PHP.
Обычно json_decode()
возвращает объект \ stdClass, если элемент верхнего уровня в объекте JSON является словарем или индексированным массивом, если объект JSON является массивом. Он также вернет скалярные значения или NULL
для определенных скалярных значений, таких как простые строки, "true"
, "false"
и "null"
. Он также возвращает NULL
при любой ошибке.
// 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]);
Используйте var_dump()
для просмотра типов и значений каждого свойства объекта, который мы расшифровали выше.
// Dump our above $object to view how it was decoded
var_dump($object);
Выход (обратите внимание на типы переменных):
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"
}
}
Примечание. Типы переменных в JSON были преобразованы в их эквивалент PHP.
Чтобы вернуть ассоциативный массив для объектов JSON вместо возвращения объекта, передайте true
как второй параметр 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);
Вывод (обратите внимание на ассоциативную структуру массива):
array(4) {
["name"] => string(4) "Jeff"
["age"] => int(20)
["active"] => bool(true)
["colors"] =>
array(2) {
[0] => string(3) "red"
[1] => string(4) "blue"
}
}
Второй параметр ( $assoc
) не действует, если возвращаемая переменная не является объектом.
Примечание. Если вы используете параметр $assoc
, вы потеряете различие между пустым массивом и пустым объектом. Это означает, что запуск json_encode()
на вашем декодированном выходе снова приведет к другой структуре JSON.
Если строка JSON имеет «глубину» более 512 элементов ( 20 элементов в версиях старше 5.2.3 или 128 в версии 5.2.3 ) в рекурсии, функция json_decode()
возвращает NULL
. В версиях 5.3 или новее этот предел можно контролировать с помощью третьего параметра ( $depth
), как обсуждается ниже.
Согласно руководству:
PHP реализует надмножество JSON, как указано в оригинале »RFC 4627 - он также кодирует и декодирует скалярные типы и NULL. RFC 4627 поддерживает только эти значения, когда они вложены внутри массива или объекта. Хотя это дополнение соответствует расширенному определению «текста JSON» в новой версии RFC 7159 (целью которого является замещение RFC 4627) и « ECMA-404» , это может вызвать проблемы совместимости со старыми анализаторами JSON, которые строго придерживаются RFC 4627, когда кодируя одно скалярное значение.
Это означает, что, например, простая строка будет считаться допустимым объектом JSON в PHP:
$json = json_decode('"some string"', true);
var_dump($json, json_last_error_msg());
Выход:
string(11) "some string"
string(8) "No error"
Но простые строки, а не в массиве или объекте, не являются частью стандарта RFC 4627 . В результате такие онлайн-шашки, как JSLint , JSON Formatter & Validator (в режиме RFC 4627) дадут вам ошибку.
Для глубины рекурсии существует третий параметр $depth
(значение по умолчанию - 512
), что означает количество вложенных объектов внутри исходного объекта, подлежащего декодированию.
Существует четвертый параметр $options
. В настоящее время он принимает только одно значение: JSON_BIGINT_AS_STRING
. Поведение по умолчанию (которое оставляет эту опцию) заключается в том, чтобы отличать целые числа от float вместо строк.
Недействительные варианты с нижним регистром истинных, ложных и нулевых литералов больше не принимаются в качестве допустимого ввода.
Итак, этот пример:
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());
До 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"
И после:
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"
Аналогичное поведение имеет место для false
и null
.
Обратите внимание, что json_decode()
возвращает NULL
если строка не может быть преобразована.
$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
Небезопасно полагаться только на возвращаемое значение NULL
для обнаружения ошибок. Например, если строка JSON содержит ничего, кроме "null"
, json_decode()
вернет значение null
, даже если ошибка не возникла.
Кодирование строки JSON
Функция json_encode
преобразует массив PHP (или, начиная с PHP 5.4, объект, который реализует интерфейс JsonSerializable
) в строку, закодированную в JSON. Он возвращает строку с кодировкой JSON при успешном завершении или FALSE при сбое.
$array = [
'name' => 'Jeff',
'age' => 20,
'active' => true,
'colors' => ['red', 'blue'],
'values' => [0=>'foo', 3=>'bar'],
];
Во время кодирования строки данных типа PHP, integer и boolean преобразуются в эквивалент JSON. Ассоциативные массивы кодируются как объекты JSON, а при вызове с аргументами по умолчанию индексированные массивы кодируются как массивы JSON. (Если ключи массива не являются непрерывной числовой последовательностью, начиная с 0, в этом случае массив будет закодирован как объект JSON.)
echo json_encode($array);
Выход:
{"name":"Jeff","age":20,"active":true,"colors":["red","blue"],"values":{"0":"foo","3":"bar"}}
аргументы
Начиная с PHP 5.3, второй аргумент json_encode
является битовой маской, которая может быть одной или несколькими из следующих.
Как и в любой битовой маске, их можно комбинировать с двоичным оператором OR |
,
JSON_FORCE_OBJECT
Заставляет создать объект вместо массива
$array = ['Joel', 23, true, ['red', 'blue']];
echo json_encode($array);
echo json_encode($array, JSON_FORCE_OBJECT);
Выход:
["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
Обеспечивает следующие преобразования во время кодирования:
постоянная | вход | Выход |
---|---|---|
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);
Выход:
{"tag":"<>","amp":"&","apos":"'","quot":"\""}
{"tag":"\u003C\u003E","amp":"\u0026","apos":"\u0027","quot":"\u0022"}
JSON_NUMERIC_CHECK
Обеспечивает преобразование числовых строк в целые числа.
$array = ['23452', 23452];
echo json_encode($array);
echo json_encode($array, JSON_NUMERIC_CHECK);
Выход:
["23452",23452]
[23452,23452]
JSON_PRETTY_PRINT
Делает JSON легко читаемым
$array = ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4];
echo json_encode($array);
echo json_encode($array, JSON_PRETTY_PRINT);
Выход:
{"a":1,"b":2,"c":3,"d":4}
{
"a": 1,
"b": 2,
"c": 3,
"d": 4
}
JSON_UNESCAPED_SLASHES
Включает неэкранированные /
косые черты на выходе
$array = ['filename' => 'example.txt', 'path' => '/full/path/to/file/'];
echo json_encode($array);
echo json_encode($array, JSON_UNESCAPED_SLASHES);
Выход:
{"filename":"example.txt","path":"\/full\/path\/to\/file"}
{"filename":"example.txt","path":"/full/path/to/file"}
JSON_UNESCAPED_UNICODE
Включает символы с кодировкой UTF8 в выводе вместо \u
-encoded строк.
$blues = ["english"=>"blue", "norwegian"=>"blå", "german"=>"blau"];
echo json_encode($blues);
echo json_encode($blues, JSON_UNESCAPED_UNICODE);
Выход:
{"english":"blue","norwegian":"bl\u00e5","german":"blau"}
{"english":"blue","norwegian":"blå","german":"blau"}
JSON_PARTIAL_OUTPUT_ON_ERROR
Позволяет продолжить кодирование, если встречаются некоторые неприменимые значения.
$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);
Выход:
{"file":null,"name":"foo.txt"}
JSON_PRESERVE_ZERO_FRACTION
Обеспечивает, чтобы поплавки всегда кодировались как плавающие.
$array = [5.0, 5.5];
echo json_encode($array);
echo json_encode($array, JSON_PRESERVE_ZERO_FRACTION);
Выход:
[5,5.5]
[5.0,5.5]
JSON_UNESCAPED_LINE_TERMINATORS
При использовании с JSON_UNESCAPED_UNICODE
возвращается к поведению старых версий PHP и не выходит из символов U + 2028 LINE SEPARATOR и U + 2029 PARAPRAPH SEPARATOR. Хотя они действительны в JSON, эти символы недействительны в JavaScript, поэтому поведение по умолчанию JSON_UNESCAPED_UNICODE
было изменено в версии 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);
Выход:
{"line":"\u2028","paragraph":"\u2029"}
{"line":"
","paragraph":"
"}
Отладка ошибок JSON
Когда json_encode
или json_decode
не удается проанализировать предоставленную строку, он вернет false
. Сам PHP не вызывает никаких ошибок или предупреждений, когда это происходит, бремя на пользователя заключается в использовании функций json_last_error () и json_last_error_msg (), чтобы проверить, произошла ли ошибка и действовать соответственно в вашем приложении (отладить ее, показать сообщение об ошибке , так далее.).
В следующем примере показана общая ошибка при работе с JSON, неспособность декодировать / кодировать строку JSON (например, из-за передачи плохой кодированной строки 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()
возвращает человекообразное сообщение о последней ошибке, возникшей при попытке кодирования / декодирования строки.
- Эта функция всегда вернет строку , даже если ошибка не возникла.
Строка по умолчанию без ошибок неNo Error
- Он вернет
false
если произошла какая-либо другая (неизвестная) ошибка - Будьте осторожны при использовании этого в циклах, поскольку json_last_error_msg будет переопределяться на каждой итерации.
Вы должны использовать эту функцию только для получения сообщения для отображения, а не для проверки в контрольных операторах.
// 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());
}
Эта функция не существует до PHP 5.5. Вот реализация полиполнения:
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()
возвращает целое число, сопоставленное с одной из предварительно определенных констант, предоставляемых PHP.
постоянная | Имея в виду |
---|---|
JSON_ERROR_NONE | Ошибка не произошла |
JSON_ERROR_DEPTH | Максимальная глубина стека превышена |
JSON_ERROR_STATE_MISMATCH | Недопустимый или некорректный JSON |
JSON_ERROR_CTRL_CHAR | Ошибка контрольного символа, возможно, неправильно закодированная |
JSON_ERROR_SYNTAX | Ошибка синтаксиса (с PHP 5.3.3) |
JSON_ERROR_UTF8 | Малоформатные символы UTF-8, возможно, некорректно закодированные (начиная с PHP 5.5.0) |
JSON_ERROR_RECURSION | Одна или несколько рекурсивных ссылок в кодируемом значении |
JSON_ERROR_INF_OR_NAN | Один или несколько значений NAN или INF в кодируемом значении |
JSON_ERROR_UNSUPPORTED_TYPE | Дано значение типа, который не может быть закодирован. |
Использование JsonSerializable в объекте
Когда вы создаете API REST, вам может потребоваться уменьшить информацию об объекте, который будет передан клиентскому приложению. С этой целью в этом примере показано, как использовать интерфейс JsonSerialiazble
.
В этом примере User
класса фактически расширяет объект модели DB гипотетической 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
];
}
}
Добавьте реализацию JsonSerializable
в класс, предоставив метод jsonSerialize()
.
public function jsonSerialize()
Теперь в вашем контроллере приложения или скрипте при передаче объекта User в json_encode()
вы получите возвращаемый json-кодированный массив метода jsonSerialize()
вместо всего объекта.
json_encode($User);
Вернусь:
{"name":"John", "surname":"Doe", "username" : "TestJson"}
пример значений свойств.
Это уменьшит количество данных, возвращаемых конечной точкой RESTful, и позволит исключить свойства объекта из представления json.
Использование частных и защищенных свойств с помощью json_encode()
Чтобы избежать использования JsonSerializable, также можно использовать частные или защищенные свойства, чтобы скрыть информацию о классе из вывода json_encode()
. Затем классу не нужно реализовывать \ JsonSerializable.
Функция json_encode () будет кодировать только общедоступные свойства класса в 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));
Выход:
string(44) "{"name":null,"surname":null,"username":null}"
Заголовок json и возвращаемый ответ
Добавив заголовок с типом контента как 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();
Заголовок там, так что ваше приложение может обнаружить, какие данные были возвращены и как он должен справиться с этим.
Обратите внимание: заголовок содержимого представляет собой только информацию о типе возвращаемых данных.
Если вы используете UTF-8, вы можете использовать:
header("Content-Type: application/json;charset=utf-8");
Пример jQuery:
$.ajax({
url:'url_your_page_php_that_return_json'
}).done(function(data){
console.table('json ',data);
console.log('Menu1 : ', data.menu1);
});