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, если:
- Нужно сохранить объекты с сохранением классов