cloud-castle/serialize

Безопасная сериализация для PHP 8.1+: PHP/JSON/igbinary из одного API, HMAC-подпись, белый список классов и лимит размера при десериализации, маппинг объект↔массив и экспорт в PHP-код. Нулевые внешние зависимости.

Maintainers

Package info

gitverse.ru/cloud-castle/serialize

Homepage

Issues

Documentation

pkg:composer/cloud-castle/serialize

Transparency log

Statistics

Installs: 113

Dependents: 4

Suggesters: 0

v1.2.1 2026-07-27 20:41 UTC

README

🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano

CloudCastle Serialize

CloudCastle Serialize

Packagist Version PHP Version License Downloads Monthly Downloads Stars Dependents Suggesters

Репозиторий Пайплайны Задачи Релизы Wiki Обсуждения

PHPStan Psalm PHPMD PHPCS Coverage Infection MSI OpenSSF Scorecard

Один API для восьми форматов сериализации PHP с безопасностью по умолчанию: объекты не восстанавливаются без явного разрешения, а нагрузку можно подписать, зашифровать, сжать и ограничить сроком жизни. Нулевые обязательные зависимости.

Установка

composer require cloud-castle/serialize

Требуется PHP 8.1+. Форматы igbinary и MessagePack используют одноимённые расширения; всё остальное работает на стандартной сборке PHP.

Быстрый старт

<?php

use CloudCastle\Serialize\Context;
use CloudCastle\Serialize\Serializer;

// PHP-формат: объекты запрещены по умолчанию (защита от gadget-chain).
$payload = Serializer::php([Order::class])->serialize($order);
$order   = Serializer::php([Order::class])->unserialize($payload);

// Восемь форматов за одним интерфейсом.
$json   = Serializer::json()->serialize($data);
$xml    = Serializer::xml()->serialize($data);          // типы не теряются
$csv    = Serializer::csv()->serialize($rows);
$yaml   = Serializer::yaml()->serialize($config);
$ndjson = Serializer::ndjson()->serialize($collection); // построчный поток

// Защита нагрузки собирается композицией: подпись, TTL, сжатие, шифрование.
$token  = Serializer::signed($key, Serializer::expiring(3600, Serializer::json()));
$sealed = $token->seal(['user' => 42]);
$data   = $token->unseal($sealed);   // подделка и просрочка отклоняются до разбора

// Анонимные функции и объекты анонимных классов — на любой глубине структуры.
$codec = Serializer::dynamic($key);
$payload = $codec->serialize([
    'handler' => static fn (int $x): int => $x * 2,
    'policy'  => new class { public int $limit = 10; },
]);
$data = $codec->unserialize($payload);
$data['handler'](21);      // 42
$data['policy']->limit;    // 10

// Маппинг объектов: группы, версии схемы, маскирование персональных данных.
$public = Serializer::mapper()->toArray($order, Context::create()->withGroups(['public']));
$safe   = Serializer::mapper()->toArray($order, Context::forLogging()); // ПД замаскированы
$order  = Serializer::mapper()->fromArray(Order::class, $public);

Возможности

  • Восемь форматов за единым интерфейсом: PHP, JSON, XML, CSV, YAML, NDJSON, igbinary, MessagePack — плюс экспорт в исполняемый PHP-код.
  • Безопасность по умолчанию: объекты не восстанавливаются без белого списка, размер и глубина нагрузки ограничены, XML отклоняет DTD, распаковка архива лимитирована.
  • Защита нагрузки композицией: HMAC-подпись с ротацией ключей, шифрование XSalsa20-Poly1305, срок жизни, прозрачное сжатие — в любых сочетаниях.
  • Маппинг объект ↔ массив на атрибутах: группы, версии схемы, стратегии именования, типизированные коллекции, полиморфизм, маскирование ПД для логов.
  • Потоковая обработка коллекций: запись и чтение по одному элементу — пиковая память не зависит от размера набора.
  • Анонимные функции и объекты анонимных классов переносятся сквозь любую структуру — с обязательной подписью кода, поскольку нагрузка исполняемая.
  • Ноль обязательных зависимостей — ни одной транзитивной уязвимости.

Описание каждой возможности с примерами, диаграммами и сравнением с аналогами — в wiki.

Сравнение с аналогами

Все таблицы ниже сгенерированы автоматически из честных сравнительных прогонов (benchmarks/compare.php): каждое решение выполняет одинаковую работу на PHP 8.1.34 без Xdebug.

1. Функциональность

ВозможностьCloudCastlesymfony/serializerjms/serializervalinorvar-exportervarexporterserializable-closuresymfony/yaml🏆 Победитель
Формат PHP (native serialize)CloudCastle
Формат JSONCloudCastle, symfony/serializer …
Формат XMLCloudCastle, symfony/serializer …
Формат CSVCloudCastle, symfony/serializer
Формат YAMLCloudCastle, symfony/serializer …
Формат NDJSON (построчный поток)CloudCastle
Формат igbinaryCloudCastle
Формат MessagePackCloudCastle
Экспорт в исполняемый PHP-кодCloudCastle, var-exporter …
Маппинг объект ↔ массивCloudCastle, symfony/serializer …
Типизированные коллекции без docblock-парсингаCloudCastle, jms/serializer …
Полиморфизм по карте дискриминатораCloudCastle, symfony/serializer …
Группы сериализацииCloudCastle, symfony/serializer …
Версионирование схемы (since/until)CloudCastle, jms/serializer
Стратегии именования (snake/kebab/pascal)CloudCastle, symfony/serializer …
Маскирование персональных данных для логовCloudCastle
Белый список классов при десериализацииCloudCastle
Лимит размера нагрузкиCloudCastle
Лимит вложенности графа объектовCloudCastle, symfony/serializer
HMAC-подпись нагрузкиCloudCastle, serializable-closure
Ротация ключей подписи без простояCloudCastle
Шифрование нагрузки (XSalsa20-Poly1305)CloudCastle
Срок жизни нагрузки (TTL)CloudCastle
Прозрачное сжатие нагрузкиCloudCastle
Сериализация замыканийCloudCastle, serializable-closure
Анонимные функции внутри произвольных структурCloudCastle
Сериализация объектов анонимных классовCloudCastle
Потоковая запись и чтение коллекцийCloudCastle
Обнаружение циклических ссылокCloudCastle, symfony/serializer
Ноль обязательных зависимостейCloudCastle
Всего3010931121🏆 CloudCastle

2. Безопасность и корректность

СвойствоCloudCastlesymfony/serializerjms/serializervalinorvar-exportervarexporterserializable-closuresymfony/yaml🏆 Победитель
Объекты запрещены при десериализации по умолчаниюCloudCastle, symfony/serializer …
Белый список классов вместо «доверяем нагрузке»CloudCastle, symfony/serializer …
Лимит размера нагрузки до разбораCloudCastle
Лимит вложенности графаCloudCastle, symfony/serializer
HMAC-подпись со сверкой за константное времяCloudCastle
Ротация ключей подписиCloudCastle
Аутентифицированное шифрование нагрузкиCloudCastle
Ограничение срока действия нагрузкиCloudCastle
Запрет DTD при разборе XML (анти-XXE)CloudCastle
Лимит распаковки архива (анти-zip-бомба)CloudCastle
Маскирование персональных данных в логахCloudCastle
Обязательная подпись при сериализации кодаCloudCastle, serializable-closure
Контрактные исключения вместо предупрежденийCloudCastle, symfony/serializer …
Ноль транзитивных зависимостей в рантаймеCloudCastle
Всего144331112🏆 CloudCastle

3. Качество кода

МетрикаCloudCastlesymfony/serializerjms/serializervalinorvar-exportervarexporterserializable-closuresymfony/yaml🏆 Победитель
Обязательных зависимостей в рантайме02421102🏆 CloudCastle
Файлов со строгой типизацией, %100010098.4010000🏆 CloudCastle
Строк кода57811193313999232972981123827513328без победителя
Строк кода на одну возможность1931193155577662981123813763328🏆 CloudCastle

4. Производительность

20 000 итераций, минимум из 3 прогонов, мс.

РешениеCloudCastlesymfony/serializerjms/serializervalinorvar-exportervarexporterserializable-closuresymfony/yamlserialize¹json¹igbinary¹msgpack¹var_export¹🏆 Победитель
Round-trip вложенной структуры56,983,9471,547,373,333,645🏆 CloudCastle
Маппинг объекта в массив и обратно287,1993,31 124,3🏆 CloudCastle
Экспорт значения в исполняемый PHP-код165,7421,4538,271,2🏆 CloudCastle
Round-trip конфигурации в YAML968,15 014,4🏆 CloudCastle
Round-trip замыкания2 939,31 208,1🏆 serializable-closure

5. Потребление памяти

пик памяти самой библиотеки на 20 000 итераций (изолированный процесс, вычет базовой линии), KB.

РешениеCloudCastlesymfony/serializerjms/serializervalinorvar-exportervarexporterserializable-closuresymfony/yamlserialize¹json¹igbinary¹msgpack¹var_export¹🏆 Победитель
Round-trip вложенной структуры47291 0511111🏆 symfony/serializer
Маппинг объекта в массив и обратно1871 0261 283🏆 CloudCastle
Экспорт значения в исполняемый PHP-код44751 2351🏆 CloudCastle
Round-trip конфигурации в YAML87380🏆 CloudCastle
Round-trip замыкания5 0545 330🏆 CloudCastle

¹ Базовый уровень — нативные функции PHP и расширения без полноты решения: они показаны для контекста и не претендуют на победу среди библиотек.

Честно о плюсах и минусах

Сильные стороны

  • Функциональный суперсет: всё, что умеют сравниваемые библиотеки вместе взятые, плюс подпись, шифрование, TTL, сжатие, потоковый формат и маскирование персональных данных.
  • Быстрее аналогов во всех измеренных сценариях и заметно экономнее по памяти на маппинге объектов.
  • Безопасность заложена в поведение по умолчанию, а не в советы из документации.
  • Нет зависимостей: обновление пакета не тянет чужие уязвимости и конфликты версий.

Ограничения, о которых стоит знать

  • На простом round-trip массива нативные serialize() и igbinary быстрее: библиотека добавляет проверки, которых у них нет. Если данные заведомо доверенные и нужен максимум скорости — берите нативные функции.
  • По удерживаемой памяти на round-trip JSON symfony/serializer немного экономнее — осознанный компромисс в пользу функциональности и проверок.
  • YAML поддержан подмножеством спецификации (отображения, списки, скаляры, комментарии): якоря, теги и многодокументные потоки не разбираются.
  • Перенос анонимных функций и объектов восстанавливает код, но не привязку $this, не область видимости класса и не статические свойства; объявление должно быть единственным на строке исходного файла.
  • Экосистемных интеграций (бандлы, провайдеры фреймворков) пока нет — подключение ручное.

Где применять

ЗадачаРекомендация
Очереди и фоновые задачиSerializer::signed() поверх php() — подделанное сообщение отбрасывается до разбора
Cookie и клиентские токеныsigned() + expiring() + compressed() — компактно, tamper-proof, с TTL
Межсервисный обменjson() или msgpack() для языковой нейтральности, поверх — подпись
Персональные и платёжные данныеencrypted() для хранения, Context::forLogging() для логов
Конфигурации приложенияyaml() для правки человеком, exporter() для opcache-кэша
Выгрузки и отчётыcsv() с типизированными заголовками, ndjson() для больших наборов
Коллекции в миллионы записейndjson()->writeTo() и readFrom() — постоянное потребление памяти
API с версионированием контрактаmapper() с атрибутами #[Since], #[Until] и группами
Недоверенный ввод из внешнего мираphp() без белого списка либо json() — лимиты уже включены
Правила и обработчики в конфигурацииdynamic() — замыкания и анонимные объекты переносятся с подписью

Когда пакет не нужен: одноразовый json_encode() внутри одного процесса, работа исключительно с доверенными данными без требований к безопасности или уже настроенный symfony/serializer в Symfony-проекте, где единообразие с фреймворком важнее перечисленных возможностей.

Разработка

composer install
composer check        # линтеры + статический анализ + тесты
composer fix          # автоисправления (Rector, PHP CS Fixer, PHPCBF)
composer ci           # полный CI-пайплайн локально
composer docs:build   # пересборка сравнительных таблиц из реальных прогонов

Полный список команд с описаниями: composer run-script --list.

Документация

Лицензия

MIT © CloudCastle (alex-4-17@yandex.ru)

🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano