cloud-castle/parser-json

Безопасный разбор и сериализация JSON для PHP 8.1+: исключения вместо тихого null, лимит глубины, безопасные дефолты кодирования и типизированные помощники. Единственная зависимость — ext-json.

Maintainers

Package info

gitverse.ru/cloud-castle/parser-json

Homepage

Issues

Documentation

pkg:composer/cloud-castle/parser-json

Transparency log

Statistics

Installs: 12

Dependents: 1

Suggesters: 1

v1.1.1 2026-07-24 11:17 UTC

This package is auto-updated.

Last update: 2026-07-29 09:11:57 UTC


README

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

CloudCastle Parser Json

CloudCastle Parser Json

Packagist Version Downloads PHP Version License

Безопасный разбор и сериализация JSON для PHP 8.1+: всегда бросает исключение при ошибке (не тихий null), лимит глубины вложенности, безопасные дефолты кодирования и типизированные помощники. Исключения не содержат исходных данных — безопасно для логов с персональными данными. Единственная зависимость — ext-json.

Установка

composer require cloud-castle/parser-json

Требуется PHP 8.1+ и расширение ext-json.

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

<?php

use CloudCastle\Parser\Json\Json;

// Разбор в ассоциативные массивы — при ошибке бросается MalformedJsonException.
$data = Json::decode('{"user":{"id":42},"tags":["a","b"]}');

// Гарантированно массив на верхнем уровне (иначе исключение).
$list = Json::toArray('[1,2,3]');

// Разбор объектов как stdClass.
$object = Json::decodeObject('{"id":42}');

// Сериализация с безопасными дефолтами (читаемый юникод, без экранирования слэшей).
$json = Json::encode(['url' => 'http://a/b', 'имя' => 'Значение']);
// {"url":"http://a/b","имя":"Значение"}

// Человекочитаемый вывод с отступами.
echo Json::pretty(['a' => 1, 'b' => [2, 3]]);

// Проверка без исключения.
if (Json::isValid($input)) {
    // ...
}

// Ограничение глубины вложенности (защита от глубоких структур).
$safe = Json::decode($untrusted, depth: 8);

// Разбор из локального файла.
$data = Json::decodeFile('/path/to/data.json');

// Автоопределение источника: локальный путь или URL. Загрузка по URL
// делегируется PSR-18 клиенту (лимит размера, таймауты и защита от SSRF —
// на стороне клиента, например cloud-castle/http-client).
$data = Json::decodeFrom('https://example.com/data.json', $httpClient, $requestFactory);
$data = Json::decodeFrom('/path/to/data.json'); // тот же метод — локальный файл

Возможности

  • Fail-loud: любая ошибка разбора или сериализации — исключение (MalformedJsonException/EncodingException), а не молчаливый null/false, который легко пропустить.
  • Лимит глубины вложенности (по умолчанию 512) — защита от переполнения стека на злонамеренно/случайно глубоких структурах.
  • Безопасные дефолты кодирования: JSON_UNESCAPED_UNICODE (читаемый юникод) и JSON_UNESCAPED_SLASHES (без лишнего экранирования).
  • Исключения не содержат исходных данных — только причину сбоя, чтобы персональные и финансовые данные из JSON не утекли в логи и трассировки.
  • Типизированные помощники: toArray() гарантирует массив, decodeObject() — объектную форму, isValid() — проверку без исключения.
  • Загрузка из файла и по URL: decodeFile() (локальный файл) и decodeFrom() (автоопределение локального пути или URL). Сеть не встроена — загрузка по URL идёт через инъектируемый PSR-18 клиент, где и задаются лимит размера, таймауты и защита от SSRF (например, cloud-castle/http-client).
  • Единственная runtime-зависимость — расширение ext-json (контракты PSR-18/17 нужны только для загрузки по URL).

Коротко

Безопасная обёртка над ext-json для разбора JSON из недоверенных источников: fail-loud вместо тихого null, лимит глубины, типизированные помощники и исключения без исходных данных (безопасно для логов с ПД), плюс загрузка из файла/URL с контролем размера и SSRF. Лидер по функционалу, скорости и безопасности среди JSON-обёрток; по памяти — наравне со всеми (разбор даёт идентичную структуру).

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

Все таблицы ниже сгенерированы автоматически из честных сравнительных тестов (benchmarks/compare.php) на ОДИНАКОВОЙ операции для всех аналогов, PHP 8.1.34, без Xdebug.

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

Возможность🏆 CloudCastlesymfonynettelaminasjson¹
Исключение при любой ошибке (не тихий null/false)
Лимит глубины вложенности (защита от глубоких структур)
Типизированные помощники (toArray/decodeObject)
Исключения не содержат исходных данных (безопасно для логов с ПД)
Ноль зависимостей сверх ext-json
Загрузка из файла/URL с контролем размера и SSRF (PSR-18)
Всего🏆 62212

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

Свойство🏆 CloudCastlesymfonynettelaminasjson¹
Fail-loud: исключение вместо пропущенного null по умолчанию
Лимит глубины (защита от переполнения стека на глубоком JSON)
Исключения не раскрывают исходные данные (нет утечки ПД в логи)
Читаемый юникод без искажения (JSON_UNESCAPED_UNICODE)
Проверка типа результата (toArray отвергает неожиданный корень)
Всего🏆 53311

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

encode + decode структуры данных, 100 000 раз (минимум из 4).

РешениеВремя (мс)Итог
json¹692,4базовый уровень (не библиотека)
🏆 CloudCastle1 323,4быстрейшее среди библиотек
nette1 354,7аналог
symfony1 973,7аналог
laminas2 324,9аналог

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

Фактически занятая память 100 000 удержанных результатов разбора (изолированный процесс).

РешениеПиковая память (KB)Итог
🏆 symfony193 944легчайшее среди библиотек
json¹193 944базовый уровень (не библиотека)
nette193 953аналог
CloudCastle193 968аналог
laminas193 981аналог

¹ Базовый уровень (нативные вызовы/примитивы без полноты решения) показан для контекста и не претендует на победу среди библиотек-аналогов.

О памяти честно. Замер — фактически занятая память (memory_get_usage) при удержании 100 000 результатов разбора в изолированном процессе. Все JSON-парсеры декодируют в идентичную структуру данных, поэтому память на удержание результата у всех одинакова (различия <0,02% — в пределах шума). Память здесь не различающая ось; реальные различия — в скорости (пакет быстрейший) и функционале/безопасности (пакет лидер).

Плюсы, минусы и когда применять

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

  • Функционал = объединение аналогов — единственный совмещает fail-loud, лимит глубины, типизированные помощники, безопасные исключения (без исходных данных), загрузку из файла/URL с контролем размера и SSRF — при нуле зависимостей сверх ext-json.
  • Быстрейший разбор среди библиотек — быстрее symfony/serializer, nette/utils, laminas-json; вплотную к «голому» ext-json (baseline).
  • Безопасность — исключение вместо тихого null/false, лимит глубины (защита от переполнения стека), исключения не раскрывают исходные данные — безопасно для логов с ПД (лидер по таблице безопасности).
  • Память — наравне с самыми лёгкими: разбор даёт идентичную структуру, расход одинаков у всех (различия в пределах шума).

Слабые стороны (честно):

  • Тонкая обёртка над ext-json — не самостоятельный парсер; при экзотических требованиях к производительности «голый» json_decode минимально быстрее (ценой тихих ошибок и отсутствия защит).
  • Не сериализатор объектов — для маппинга JSON ↔ типизированные DTO берите symfony/serializer (здесь фокус на безопасном разборе данных, а не на гидрации).

Когда применять. Везде, где JSON приходит из недоверенного источника (API, конфиги, очереди) и важны предсказуемая обработка ошибок, защита от глубоких структур и отсутствие утечки персональных данных в логи. Для маппинга в типизированные объекты — symfony/serializer; для микро-выигрыша скорости ценой безопасности — ext-json.

Разработка

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

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

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

Лицензия

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

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