Как лучше хранить массивы PHP: json_encode против serialize? Сравнение и производительность
Сравнение json_encode и serialize: подробный разбор
Отличный вопрос! Давайте разберем оба метода по косточкам. Начну с главного: не существует универсально лучшего метода — выбор зависит от вашей задачи.
1. Производительность (скорость)
В большинстве современных версиях PHP (7.4+) serialize работает на 20-40% быстрее для простых массивов. Однако json_encode быстрее для сложных вложенных структур. Рекомендую протестировать на своих данных:
// Тест производительности
$start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
$json = json_encode($data);
}
echo 'json_encode: ' . (microtime(true) - $start) . ' сек';
$start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
$ser = serialize($data);
}
echo 'serialize: ' . (microtime(true) - $start) . ' сек';
2. Размер данных
json_encode обычно создает меньший по размеру файл (на 10-30%). Это связано с тем, что JSON не хранит информацию о типах данных и длине строк. Пример:
$data = [
'name' => 'Александр',
'age' => 30,
'active' => true
];
echo strlen(json_encode($data)); // 47 байт
echo strlen(serialize($data)); // 69 байт
3. Безопасность
JSON безопаснее. unserialize() может выполнить произвольный код при десериализации недоверенных данных (известная уязвимость). Никогда не используйте unserialize() для данных из пользовательского ввода! json_decode() безопасен — он создает только простые объекты/массивы.
4. Поддержка типов данных
serialize поддерживает все типы PHP, включая:
- Объекты (с сохранением класса)
- Ресурсы (но их нельзя сериализовать)
- NULL, булевы значения
- Специальные типы (например, SimpleXML)
json_encode поддерживает только:
- Скаляры (int, float, string, bool, null)
- Массивы
- Объекты (с публичными свойствами)
Важно: json_encode преобразует все ключи массивов в строки, а serialize сохраняет оригинальные типы ключей.
5. Совместимость с другими системами
JSON — стандарт де-факто для обмена данными между системами. Его читают JavaScript, Python, Java и любой другой язык. serialize — это внутренний формат PHP, который нельзя использовать за пределами экосистемы PHP.
Практические рекомендации
- Для кеширования данных внутри PHP — используйте
serialize(быстрее, сохраняет типы) - Для хранения конфигураций или данных, которые будут читаться не из PHP — используйте
json_encode - Для пользовательского ввода или данных из внешних источников — только
json_decode(безопасность) - Для больших объемов данных — тестируйте оба метода, так как производительность зависит от структуры данных
Пример правильного кеширования с serialize:
function getCachedData($key) {
$file = "cache/{$key}.cache";
if (file_exists($file) && (time() - filemtime($file)) < 3600) {
return unserialize(file_get_contents($file));
}
$data = heavyDatabaseQuery();
file_put_contents($file, serialize($data));
return $data;
}
И с JSON для конфигурации:
function loadConfig() {
$json = file_get_contents('config.json');
return json_decode($json, true); // true для получения массива
}
<<Альтернативный подход: igbinary и другие сериализаторы
Если производительность критична, рассмотрите igbinary — это расширение PHP, которое заменяет стандартный сериализатор. Оно работает в 2-3 раза быстрее и создает файлы на 30-50% меньше, чем serialize.
// С igbinary
$data = igbinary_serialize($array);
$array = igbinary_unserialize($data);
// Для файлового кеша
file_put_contents('cache.igb', igbinary_serialize($data));
$data = igbinary_unserialize(file_get_contents('cache.igb'));
Плюсы igbinary:
- Значительно быстрее стандартного serialize
- Меньший размер данных
- Поддерживает все типы PHP
Минусы:
- Требует установки расширения (не входит в стандартную поставку PHP)
- Не совместим с другими языками
- Может быть проблемы при обновлении PHP (обратная совместимость не гарантируется)
Еще один вариант — MessagePack (через расширение msgpack). Он дает бинарный формат, похожий на JSON, но компактнее и быстрее. Хорошо подходит для передачи данных между PHP и Python/Ruby.
Итог: Для большинства проектов хватит json_encode (безопасность, совместимость) или serialize (скорость, типы). igbinary — нишевое решение для высоконагруженных систем, где каждый миллисекунда на счету.
Советую начать с JSON — это самый универсальный и безопасный вариант. Переходите на serialize только если замеры покажут, что JSON является узким местом производительности.