Поиск…


Вступление

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 | ,

PHP 5.x 5.3

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"}
PHP 5.x 5.3

JSON_NUMERIC_CHECK

Обеспечивает преобразование числовых строк в целые числа.

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

Выход:

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

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"}
PHP 5.x 5.5

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"}
PHP 5.x 5.6

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]
PHP 7.x 7.1

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 в объекте

PHP 5.x 5.4

Когда вы создаете 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);
    });


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow