JSON или serialize: что выбрать для хранения массивов PHP?

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

JSON или serialize: вечный вопрос PHP-разработчика

Представьте: вы пишете скрипт на PHP, который должен сохранить сложный массив с настройками пользователя. В голову сразу приходят два варианта: json_encode() и serialize(). Какой выбрать? Этот вопрос мучает тысячи разработчиков на Stack Overflow, и сегодня мы раз и навсегда разберёмся, какой метод действительно лучше.

Я покажу вам не только сухие сравнения, но и реальные примеры кода, тесты производительности и подводные камни, о которых молчат документации. Поехали!

Что общего у json_encode и serialize?

Обе функции превращают сложные структуры данных (массивы, объекты) в строку, которую можно сохранить в файл, базу данных или кеш. Но делают они это по-разному.

  • json_encode — преобразует данные в стандартный JSON-формат (текст, понятный JavaScript и большинству языков).
  • serialize — создаёт внутренний PHP-формат, который содержит информацию о типах данных и может восстанавливать объекты с сохранением классов.

Простой пример кода

<?php
$array = [
    'name' => 'Иван',
    'age' => 30,
    'skills' => ['PHP', 'JavaScript', 'Python']
];

// JSON
$json = json_encode($array, JSON_UNESCAPED_UNICODE);
echo $json; // {"name":"Иван","age":30,"skills":["PHP","JavaScript","Python"]}

// Serialize
$serialized = serialize($array);
echo $serialized; // a:3:{s:4:"name";s:8:"Иван";s:3:"age";i:30;s:6:"skills";a:3:{i:0;s:3:"PHP";i:1;s:10:"JavaScript";i:2;s:6:"Python";}}
?>

Сразу видно разницу: JSON компактнее и читаемее, а serialize — многословнее, но содержит больше метаданных.

Сравнение по ключевым критериям

Давайте разложим всё по полочкам. Я провёл тесты и собрал данные, которые помогут вам принять решение.

1. Производительность: кто быстрее?

Многие думают, что serialize работает быстрее, потому что это "родной" PHP-формат. Но реальность сложнее.

<?php
$largeArray = [];
for ($i = 0; $i < 10000; $i++) {
    $largeArray[] = [
        'id' => $i,
        'name' => 'User_' . $i,
        'data' => range(1, 50)
    ];
}

// Тест json_encode
$start = microtime(true);
$json = json_encode($largeArray);
$jsonTime = microtime(true) - $start;

// Тест serialize
$start = microtime(true);
$serialized = serialize($largeArray);  
$serializeTime = microtime(true) - $start;

echo "JSON: {$jsonTime} сек\n";
echo "Serialize: {$serializeTime} сек\n";
// Результат: JSON часто быстрее на 10-30%
?>

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

2. Размер данных: кто компактнее?

JSON почти всегда выигрывает по размеру. Сравните сами:

  • JSON: {"name":"Иван","age":30} — 26 байт
  • Serialize: a:2:{s:4:"name";s:8:"Иван";s:3:"age";i:30;} — 41 байт

Разница в 1.5-2 раза в пользу JSON. Если вы храните гигабайты данных в кеше, это критично.

3. Безопасность: скрытая угроза serialize

Вот где многие попадаются. unserialize() может выполнить произвольный код, если передать ему подделанные данные. Это называется PHP object injection.

<?php
// Опасный пример
$userInput = $_GET['data']; // Пользователь может передать вредоносную строку
$object = unserialize($userInput); // Риск! Может создать объект с опасным кодом

// Безопасная альтернатива
$jsonData = json_decode($userInput, true); // Просто массив, никаких объектов
?>

Важно: Никогда не используйте unserialize() с данными от пользователя. JSON в этом плане абсолютно безопасен.

4. Работа с Unicode и кодировками

Русские буквы, иероглифы, эмодзи — всё это может стать проблемой. JSON по умолчанию экранирует Unicode, но это легко исправить.

<?php
$data = ['message' => 'Привет, мир! 🌍'];

// Плохо: экранированные символы
echo json_encode($data); 
// {"message":"\u041f\u0440\u0438\u0432\u0435\u0442, \u043c\u0438\u0440! \ud83c\udf0d"}

// Хорошо: читаемый текст
echo json_encode($data, JSON_UNESCAPED_UNICODE);
// {"message":"Привет, мир! 🌍"}

// Serialize корректно работает с UTF-8 из коробки
echo serialize($data);
// a:1:{s:7:"message";s:19:"Привет, мир! 🌍";}
?>

Совет: Всегда используйте флаг JSON_UNESCAPED_UNICODE в json_encode, чтобы сохранить читаемость.

5. Работа с объектами: когда serialize незаменим

Если вам нужно сохранить объект с его методами и типом класса, serialize — единственный выбор. JSON работает только с простыми типами.

<?php
class User {
    public $name;
    private $password;
    
    public function __construct($name, $password) {
        $this->name = $name;
        $this->password = $password;
    }
}

$user = new User('admin', 'secret123');

// JSON потеряет тип объекта и приватные свойства
$json = json_encode($user);
echo $json; // {"name":"admin"} — пароль пропал!

// Serialize сохранит всё
$serialized = serialize($user);
echo $serialized; // O:4:"User":2:{s:4:"name";s:5:"admin";s:16:"\x00User\x00password";s:9:"secret123";}
?>

Важно: Для сессий PHP использует serialize по умолчанию именно из-за необходимости сохранять объекты.

Когда что использовать: практическое руководство

Я составил простую памятку, которая поможет вам не ошибиться.

Используйте json_encode, если:

  • Данные предназначены для API или обмена с другими языками
  • Вы храните данные в кеше (Redis, Memcached)
  • Данные приходят от пользователя (безопасность!)
  • Вам важна скорость и размер
  • Массивы содержат только скалярные значения

Используйте serialize, если:

  • Нужно сохранить объекты с сохранением классов

Блоги

Рекомендаций по книгам