json_encode
Returns a string containing the JSON representation of value.
JSON (англ. JavaScript Object Notation) — текстовый формат обмена данными, основанный на JavaScript и обычно используемый именно с этим языком. Как и многие другие текстовые форматы, JSON легко читается людьми.
Список параметров
The value being encoded. Can be any type except a resource .
Возвращаемые значения
Возвращает данные в формате JSON string on success.
Примеры
Пример 1. A json_encode() example
$arr = array ('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5); echo json_encode($arr);
Результат выполнения данного примера:
Пример 2. A json_encode()
$json_data = array ('id'=>1,'name'=>"ivan",'country'=>'Russia',"office"=>array("yandex"," management")); echo json_encode($json_data);
Пример 3. Эмулятор json_encode()
if (!function_exists('json_encode')) < function json_encode_($a=false) < if (is_null($a)) return 'null'; if ($a === false) return 'false'; if ($a === true) return 'true'; if (is_scalar($a)) < if (is_float($a)) < // Always use "." for floats. return floatval(str_replace(",", ".", strval($a))); >if (is_string($a)) < static $jsonReplaces = array(array("\\", "/", "\n", "\t", "\r", "\b", "\f", '"'), array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"')); return '"' . str_replace($jsonReplaces[0], $jsonReplaces[1], $a) . '"'; >else return $a; > $isList = true; for ($i = 0, reset($a); $i $v) $result[] = json_encode_($k).':'.json_encode_($v); return ''; > > >
Пример 3. Сохранение русских букв(кирилицы) при использовании json_encode()
А вот пример кодирования сервером строки JSON при помощи стандартной функции в php «json_encode()» и добавочной к ней. В результате русские буковки остаются русскими. Начиная с версии PHP 5.4.0. можно воспользоваться стандартныой опцией JSON_UNESCAPED_UNICODE
Исходный объект в кодировке UTF-8.
function json_encode_cyr($str)
Проблемы с которыми сталкиваются программисты
Доступ к полям
Проблема заключается в том что json_encode имеет доступ только к публичным полям объекта. Например если у вас есть класс
class Example < public $publicProperty; protected $protectedProperty; private $privateProperty; public function __construct($public, $protected, $private) < $this->publicProperty = $public; $this->protectedProperty = $protected; $this->privateProperty = $private; > >
то результатом выполнения следующего кода будет:
$obj = new Example("some", "value", "here"); echo json_encode($obj); //
как видно в результирующий json были включены только публичные поля.
Что же делать если нужны все поля?
Для php >= 5.4 достаточно будет реализовать интерфейс JsonSerializable для нашего класса, что подразумевает добавление метода jsonSerialize который будет возвращать структуру представляющую объект для json_encode
class Example implements JsonSerializable < public $publicProperty; protected $protectedProperty; private $privateProperty; public function __construct($public, $protected, $private) < $this->publicProperty = $public; $this->protectedProperty = $protected; $this->privateProperty = $private; > public function jsonSerialize() < return [ 'publicProperty' =>$this->publicProperty, 'protectedProperty' => $this->protectedProperty, 'privateProperty' => $this->privateProperty, ]; > >
Теперь мы можем использовать json_encode как и раньше
$obj = new Example("some", "value", "here"); echo json_encode($obj); //
Почему не стоит использовать подход с toJson методом?
Многие наверно заметили что подход с созданием метода возвращающего json может быть использован и в версиях php >= 5.4. Так почему же не воспользоваться им? Все дело в том что ваш класс может быть использован как часть иной структуры данных
echo json_encode([ 'status' => true, 'message' => 'some message', 'data' => new Example("some", "value", "here"), ]);
и результат уже будет совсем другой. Также класс может использоваться другими программистами, для которых такой тип получение json-а с объекта может быть не совсем очевиден.
Что если у меня очень много полей в класcе?
В таком случае можно воспользоваться функцией get_object_vars
class Example implements JsonSerializable < public $publicProperty; protected $protectedProperty; private $privateProperty; protected $someProp1; . protected $someProp100500; public function __construct($public, $protected, $private) < $this->publicProperty = $public; $this->protectedProperty = $protected; $this->privateProperty = $private; > public function jsonSerialize() < $fields = get_object_vars($this); // что-то делаем . return $fields; >>
А если нужно private-поля, из класса, который нет возможности редактировать?
Может получиться ситуация когда нужно получить private поля (именно private, т.к. доступ к protected полям можно получить через наследование) в json-е. В таком случае необходимо будет воспользоваться рефлексией:
class Example < public $publicProperty = "someValue"; protected $protectedProperty; private $privateProperty1; private $privateProperty2; private $privateProperty3; public function __construct($privateProperty1, $privateProperty2, $privateProperty3, $protectedProperty) < $this->protectedProperty = $protectedProperty; $this->privateProperty1 = $privateProperty1; $this->privateProperty2 = $privateProperty2; $this->privateProperty3 = $privateProperty3; > > $obj = new Example("value1", 12, "21E021", false); $reflection = new ReflectionClass($obj); $public = []; foreach ($reflection->getProperties() as $property) < $property->setAccessible(true); $public[$property->getName()] = $property->getValue($obj); > echo json_encode($public); //
Кодировка текстовых значений
Кириллица и другие знаки в UTF8
Второй тип распространённых проблем с json_encode это проблемы с кодировкой. Часто текстовые значения которые нужно кодировать в json имеют в себе символы в UTF8 (в том числе кириллица) в результате эти символы будут представлены в виде кодов:
echo json_encode("кириллица or ₳ ƒ 元 ﷼ ₨ ௹ ¥ ₴ £ ฿ $"); // "\u043a\u0438\u0440\u0438\u043b\u043b\u0438\u0446\u0430 or \u20b3 \u0192 \u5143 \ufdfc \u20a8 \u0bf9 \uffe5 \u20b4 \uffe1 \u0e3f \uff04"
Отображение таких символов лечится очень просто — добавлением флага JSON_UNESCAPED_UNICODE вторым аргументом к функции json_encode:
echo json_encode("кириллица or ₳ ƒ 元 ﷼ ₨ ௹ ¥ ₴ £ ฿ $", JSON_UNESCAPED_UNICODE); // "кириллица or ₳ ƒ 元 ﷼ ₨ ௹ ¥ ₴ £ ฿ $"
Символы в других кодировках
Функция json_encode воспринимает строковые значения как строки в UTF8, что может вызвать ошибку, если кодировка другая. Рассмотрим маленький кусочек кода (данный пример кода максимально упрощен для демонстрации проблемной ситуации)
На первый взгляд ничего не предвещает проблем, да и что здесь может пойти не так? Я тоже так думал. В подавляющем большинстве случаев все будет работать, и по этой причине поиск проблемы занял у меня несколько больше времени, когда я впервые столкнулся с тем что результатом json_encode было false.
Для воссоздания такой ситуации предположим что p=%EF%F2%E8%F6%E0 (на пример: localhost?=%EF%F2%E8%F6%E0 ). *Переменные в суперглобальных массивах $_GET и $_REQUEST уже декодированы.
$decoded = urldecode("%EF%F2%E8%F6%E0"); var_dump(json_encode($decoded)); // bool(false) var_dump(json_last_error_msg()); // string(56) "Malformed UTF-8 characters, possibly incorrectly encoded"
Как можно увидеть из ошибки: проблема с кодировкой переданной строки (это не UTF8). Решение проблемы очевидное — привести значение в UTF8
$decoded = urldecode("%EF%F2%E8%F6%E0"); $utf8 = utf8_encode($decoded); echo json_encode($utf8); // "ïòèöà"
Цифровые значения
Последняя типовая ошибка связана с кодированием числовых значений.
echo json_encode(["string_float" => "3.0"]); //
Как известно php не строго типизированный язык и позволяет использовать числа в виде строки, в большинстве случаев это не приводит к ошибкам внутри php приложения. Но так как json очень часто используется для передачи сообщений между приложениями, такой формат записи числа может вызвать проблемы в другом приложении. Желательно использовать флаг JSON_NUMERIC_CHECK:
echo json_encode(["string_float" => "3.0"], JSON_NUMERIC_CHECK); //
Уже лучше. Но как видим «3.0» превратилось в 3, что в большинстве случаев будет интерпретировано как int. Используем еще один флаг JSON_PRESERVE_ZERO_FRACTION для корректного преобразования в float:
echo json_encode(["string_float" => "3.0"], JSON_NUMERIC_CHECK | JSON_PRESERVE_ZERO_FRACTION); //
Прошу также обратить внимание на следующий фрагмент кода, что иллюстрирует ряд возможных проблем с json_encode и числовыми значениями:
$data = [ "0000021", // нули слева 6.12345678910111213, // много знаков после точки (будет округленно) "+81011321515", // телефон "21E021", // экспоненциальная запись ]; echo json_encode($data, JSON_NUMERIC_CHECK); //[ // 21, // 6.1234567891011, // 81011321515, // 2.1e+22 // ]
json_encode
Returns a string containing the JSON representation of the supplied value . If the parameter is an array or object , it will be serialized recursively.
If a value to be serialized is an object, then by default only publicly visible properties will be included. Alternatively, a class may implement JsonSerializable to control how its values are serialized to JSON .
The encoding is affected by the supplied flags and additionally the encoding of float values depends on the value of serialize_precision.
Parameters
The value being encoded. Can be any type except a resource.
All string data must be UTF-8 encoded.
Note:
PHP implements a superset of JSON as specified in the original » RFC 7159.
Bitmask consisting of JSON_FORCE_OBJECT , JSON_HEX_QUOT , JSON_HEX_TAG , JSON_HEX_AMP , JSON_HEX_APOS , JSON_INVALID_UTF8_IGNORE , JSON_INVALID_UTF8_SUBSTITUTE , JSON_NUMERIC_CHECK , JSON_PARTIAL_OUTPUT_ON_ERROR , JSON_PRESERVE_ZERO_FRACTION , JSON_PRETTY_PRINT , JSON_UNESCAPED_LINE_TERMINATORS , JSON_UNESCAPED_SLASHES , JSON_UNESCAPED_UNICODE , JSON_THROW_ON_ERROR . The behaviour of these constants is described on the JSON constants page.
Set the maximum depth. Must be greater than zero.
Return Values
Returns a JSON encoded string on success or false on failure.
Changelog
Version | Description |
---|---|
7.3.0 | JSON_THROW_ON_ERROR flags was added. |
7.2.0 | JSON_INVALID_UTF8_IGNORE , and JSON_INVALID_UTF8_SUBSTITUTE flags were added. |
7.1.0 | JSON_UNESCAPED_LINE_TERMINATORS flags was added. |
7.1.0 | serialize_precision is used instead of precision when encoding float values. |
Examples
Example #1 A json_encode() example
$arr = array( ‘a’ => 1 , ‘b’ => 2 , ‘c’ => 3 , ‘d’ => 4 , ‘e’ => 5 );
?php
The above example will output:
Example #2 A json_encode() example showing some flags in use
echo «Normal: » , json_encode ( $a ), «\n» ;
echo «Tags: » , json_encode ( $a , JSON_HEX_TAG ), «\n» ;
echo «Apos: » , json_encode ( $a , JSON_HEX_APOS ), «\n» ;
echo «Quot: » , json_encode ( $a , JSON_HEX_QUOT ), «\n» ;
echo «Amp: » , json_encode ( $a , JSON_HEX_AMP ), «\n» ;
echo «Unicode: » , json_encode ( $a , JSON_UNESCAPED_UNICODE ), «\n» ;
echo «All: » , json_encode ( $a , JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE ), «\n\n» ;
echo «Empty array output as array: » , json_encode ( $b ), «\n» ;
echo «Empty array output as object: » , json_encode ( $b , JSON_FORCE_OBJECT ), «\n\n» ;
echo «Non-associative array output as array: » , json_encode ( $c ), «\n» ;
echo «Non-associative array output as object: » , json_encode ( $c , JSON_FORCE_OBJECT ), «\n\n» ;
$d = array( ‘foo’ => ‘bar’ , ‘baz’ => ‘long’ );
echo «Associative array always output as object: » , json_encode ( $d ), «\n» ;
echo «Associative array always output as object: » , json_encode ( $d , JSON_FORCE_OBJECT ), «\n\n» ;
?>
The above example will output:
Normal: [«»,»‘bar'»,»\»baz\»»,»&blong&»,»\u00e9″] Tags: [«\u003Cfoo\u003E»,»‘bar'»,»\»baz\»»,»&blong&»,»\u00e9″] Apos: [«»,»\u0027bar\u0027″,»\»baz\»»,»&blong&»,»\u00e9″] Quot: [«»,»‘bar'»,»\u0022baz\u0022″,»&blong&»,»\u00e9″] Amp: [«»,»‘bar'»,»\»baz\»»,»\u0026blong\u0026″,»\u00e9″] Unicode: [«»,»‘bar'»,»\»baz\»»,»&blong&»,»é»] All: [«\u003Cfoo\u003E»,»\u0027bar\u0027″,»\u0022baz\u0022″,»\u0026blong\u0026″,»é»] Empty array output as array: [] Empty array output as object: <> Non-associative array output as array: [[1,2,3]] Non-associative array output as object: > Associative array always output as object: Associative array always output as object:
Example #3 JSON_NUMERIC_CHECK option example
echo «Strings representing numbers automatically turned into numbers» . PHP_EOL ;
$numbers = array( ‘+123123’ , ‘-123123’ , ‘1.2e3’ , ‘0.00001’ );
var_dump (
$numbers ,
json_encode ( $numbers , JSON_NUMERIC_CHECK )
);
echo «Strings containing improperly formatted numbers» . PHP_EOL ;
$strings = array( ‘+a33123456789’ , ‘a123’ );
var_dump (
$strings ,
json_encode ( $strings , JSON_NUMERIC_CHECK )
);
?>?php
The above example will output something similar to:
Strings representing numbers automatically turned into numbers array(4) < [0]=>string(7) "+123123" [1]=> string(7) "-123123" [2]=> string(5) "1.2e3" [3]=> string(7) "0.00001" > string(28) "[123123,-123123,1200,1.0e-5]" Strings containing improperly formatted numbers array(2) < [0]=>string(13) "+a33123456789" [1]=> string(4) "a123" > string(24) "["+a33123456789","a123"]"
Example #4 Sequential versus non-sequential array example
echo «Sequential array» . PHP_EOL ;
$sequential = array( «foo» , «bar» , «baz» , «blong» );
var_dump (
$sequential ,
json_encode ( $sequential )
);
?php
echo PHP_EOL . «Non-sequential array» . PHP_EOL ;
$nonsequential = array( 1 => «foo» , 2 => «bar» , 3 => «baz» , 4 => «blong» );
var_dump (
$nonsequential ,
json_encode ( $nonsequential )
);
echo PHP_EOL . «Sequential array with one key unset» . PHP_EOL ;
unset( $sequential [ 1 ]);
var_dump (
$sequential ,
json_encode ( $sequential )
);
?>
The above example will output:
Sequential array array(4) < [0]=>string(3) "foo" [1]=> string(3) "bar" [2]=> string(3) "baz" [3]=> string(5) "blong" > string(27) "["foo","bar","baz","blong"]" Non-sequential array array(4) < [1]=>string(3) "foo" [2]=> string(3) "bar" [3]=> string(3) "baz" [4]=> string(5) "blong" > string(43) "" Sequential array with one key unset array(3) < [0]=>string(3) "foo" [2]=> string(3) "baz" [3]=> string(5) "blong" > string(33) ""
Example #5 JSON_PRESERVE_ZERO_FRACTION option example
The above example will output: