PHP json_encode: преобразуем данные в JSON формат

0
0

JSON - один из самых популярных форматов для хранения и обмена данными в веб-приложениях. В этой статье мы подробно разберем, как с помощью встроенной функции json_encode в PHP кодировать переменные в JSON, решать типичные проблемы в работе и извлекать максимум пользы для ваших проектов.

Что такое json_encode в PHP

Json_encode - это нативная функция PHP, которая позволяет преобразовать переменные PHP в строку в формате JSON (JavaScript Object Notation). В отличие от простого приведения к строке, json_encode генерирует структурированные и читаемые данные, готовые для обмена между клиентом и сервером.

JSON похож на ассоциативные массивы или объекты в PHP и позволяет представлять числа, строки, boolean значения, а также вложенные структуры.

Основные причины для использования json_encode в PHP:

  • Отдача данных из PHP в веб-приложение в популярном формате
  • Взаимодействие PHP и JavaScript при помощи JSON
  • Структурированный обмен данными между разными системами и сервисами

Рассмотрим простейший пример кодирования переменной в JSON:

<?php $data = array('name' => 'John', 'age' => 30); $json = json_encode($data); echo $json; // {"name":"John","age":30} 

Как видно из примера, ассоциативный массив преобразовался в JSON объект готовый для использования в JavaScript или отправки на удаленный сервис.

Печатание на клавиатуре

Кодируем разные типы данных PHP в JSON

Json_encode умеет работать практически с любыми данными в PHP: массивами, объектами, числами, boolean, null и другими типами.

Футуристический город на закате

1. Массивы

Рассмотрим пример кодирования индексного (простого) массива в JSON:

$books = [ "Война и мир", "Мастер и Маргарита", "Преступление и наказание" ]; $json_books = json_encode($books); // ["Война и мир","Мастер и Маргарита","Преступление и наказание"] 

Как видно из примера выше, индексированный массив в PHP становится массивом JSON.

Ассоциативные массивы в PHP при помощи json_encode преобразуются в объекты JSON:

$book = [ "title" => "Война и мир", "author" => "Лев Толстой", "pageCount" => 1225 ]; $json_book = json_encode($book); // {"title":"Война и мир","author":"Лев Толстой","pageCount":1225} 

2. Объекты и классы

Рассмотрим пример объекта Book и его кодирования в JSON при помощи json_encode:

class Book { public $title; public $author; public function __construct($title, $author) { $this->title = $title; $this->author = $author; } } $book = new Book("Война и мир", "Лев Толстой"); $json_book = json_encode($book); // {"title":"Война и мир","author":"Лев Толстой"} 

Как видно из примера, публичные свойства объекта Book были закодированы в JSON объект при помощи json_encode.

Рассмотрим и другие примеры использования json_encode...

Другие простые типы данных

Рассмотрим использование json_encode для кодирования чисел, логических значений и null:

$data = [ "age" => 35, "isMember" => true, "middleName" => null ]; $json = json_encode($data); // {"age":35,"isMember":true,"middleName":null} 

Как видим, разные типы данных PHP корректно преобразуются в JSON эквиваленты.

Вложенные структуры данных

Одно из преимуществ JSON в том, что он позволяет кодировать вложенные структуры. Например, массив объектов:

$books = [ ["title" => "Война и мир", "author" => "Лев Толстой"], ["title" => "Отцы и дети", "author" => "Иван Тургенев"] ]; $json_books = json_encode($books); // [{"title":"Война и мир","author":"Лев Толстой"},{"title":"Отцы и дети","author":"Иван Тургенев"}] 

Или объект с вложенным массивом:

$data = [ "name" => "John", "books" => ["Война и мир", "Анна Каренина"] ]; $json = json_encode($data); // {"name":"John","books":["Война и мир","Анна Каренина"]} 

Типичные проблемы при кодировании в JSON

Рассмотрим несколько распространенных проблем при использовании json_encode в PHP.

Кодировка русских символов

Иногда русские символы в результате json_encode могут быть закодированы неправильно. Чтобы это исправить, нужно явно указать опцию JSON_UNESCAPED_UNICODE:

$data = [ "title" => "Война и мир" ]; $json = json_encode($data, JSON_UNESCAPED_UNICODE); // {"title":"Война и мир"} 

Числовые значения

Если числа передаются в виде строк, json_encode может неправильно интерпретировать их тип. В таких случаях помогают флаги JSON_NUMERIC_CHECK и JSON_PRESERVE_ZERO_FRACTION:

$data = [ "price" => "15.20" ]; $json = json_encode($data, JSON_NUMERIC_CHECK | JSON_PRESERVE_ZERO_FRACTION); // {"price":15.2} 

Работа с ошибками

Если json_encode вернул ошибку или пустой результат, это можно проверить функцией json_last_error():

if($json === false) { $error = json_last_error(); echo "Произошла ошибка кодирования в JSON: $error"; } 

Работа с большими объемами данных

При кодировании в JSON больших массивов или запросов к базе данных, производительность json_encode может снижаться. В таких случаях есть несколько способов оптимизации:

  1. Использовать параметр JSON_PRETTY_PRINT - выключает форматирование JSON для экономии ресурсов
  2. Увеличить лимит памяти и времени выполнения в php.ini
  3. Разбить данные на части и кодировать по отдельности, объединяя результат
$data = []; // большой массив из БД $part1 = array_slice($data, 0, 1000); $part2 = array_slice($data, 1000, 2000); $json1 = json_encode($part1); $json2 = json_encode($part2); $json = "[" . $json1 . "," . $json2 . "]"; // объединяем 

Асинхронная кодировка в JSON

Еще один подход при работе с большими объемами данных - использовать асинхронную кодировку через очереди сообщений:

  1. Поместить данные для кодирования в Redis очередь
  2. В фоновом процессе читать очередь и кодировать в JSON
  3. Сохранять результаты в нужном месте
$data = []; // данные для кодирования $redis->rpush('convert_json', json_encode($data)); // add to queue $json = $redis->blpop('convert_json'); // get data $json = json_decode($json); // decode $result = json_encode($json); // encode save_results($result); // save 

Быстрое кеширование результатов

Для часто запрашиваемых данных имеет смысл кешировать уже закодированный JSON, не выполняя кодирование повторно:

$key = md5(json_encode($data)); if($cache->has($key)) { $json = $cache->get($key); } else { $json = json_encode($data); $cache->set($key, $json, 3600); } 

Заключение

Декодирование JSON обратно в PHP

Рассмотрим, как при помощи функции json_decode преобразовать данные из JSON обратно в нативные типы PHP.

Например, декодируем JSON строку в переменную:

$json = '{"name":"John","age":30}'; $data = json_decode($json); print_r($data); // stdClass Object // ( // [name] => John // [age] => 30 // ) 

По умолчанию возвращается объект stdClass. Чтобы получить ассоциативный массив, используем второй параметр:

$data = json_decode($json, true); print_r($data); // Array // ( // [name] => John // [age] => 30 // ) 

Работа с ошибками при декодировании

Аналогично json_encode, мы можем отлавливать ошибки с помощью json_last_error():

$data = json_decode($invalidJson); if($data === null) { $error = json_last_error(); echo "Произошла ошибка: $error"; } 

Декодирование вложенных структур

Рассмотрим пример декодирования сложного вложенного JSON в PHP переменные:

$json = '{"user":{"name":"John","age":30},"books":[{"title":"Война и мир"}]}'; $data = json_decode($json, true); echo $data['user']['name']; // John print_r($data['books'][0]); // Array ([title] => Война и мир) 

Прогрессивное декодирование больших объемов

При работе с большими JSON документами, можно использовать потоковое декодирование, не загружая весь документ в память: