-
-
Notifications
You must be signed in to change notification settings - Fork 0
Feature Safety
Свойства, отличающие пакет от аналогов на уровне дизайна: строгие сравнения, «строка — данные, не код», fail-safe JSON; плюс мутаторы и higher-order методы.
Все операции сравнения — contains/search/where*/diff/intersect/unique —
используют строгое сравнение. Классические PHP-ловушки исключены по построению:
use CloudCastle\Collection\Collection;
// 0 == 'admin' → true при loose; здесь — false
Collection::make([0, '1', null])->contains('admin'); // false
// '0e123' == '0e456' → true при loose (оба «нулевые» float) — вектор обхода сравнения хэшей
Collection::make(['0e123'])->search('0e456'); // false
// int 1 и string '1' — разные идентификаторы (критично для проверок прав)
$users->where('id', 1); // только int-совпадения
$users->whereIn('id', ['1']); // не найдёт int 1Имя функции, пришедшее в данных ('system', 'phpinfo'), никогда не выполняется:
Collection::make(['system', 'exec'])->contains('system'); // true — поиск значения
$rows->groupBy('trim'); // извлечение поля 'trim', не вызов trim()Строковый callable, переданный как callback в map/filter/reduce, получает
только значение — без ключа, который ломал бы встроенные функции:
Collection::make(['1', '2'])->map('intval'); // [1, 2] — ключ не попал в базу счисления
Collection::make([1, 'a'])->filter('is_int'); // [1] — без ArgumentCountError
Collection::make([1, 9, 3])->reduce('max', 0); // 9 — ключ не участвует в max()$c->toJson(); // InvalidJsonException вместо тихого false
Collection::fromJson('{broken'); // InvalidJsonException (с previous от json-декодера)
Collection::fromJson('42'); // InvalidJsonException: скаляр на верхнем уровне
Collection::fromJson($json, 64); // лимит глубины; враждебные значения клэмпятсяМутаторы изменяют текущую коллекцию (семантика illuminate): push/put/pull/forget/
prepend/pop/shift/splice. Higher-order управляют цепочкой:
$c->push(4, 5)->put('k', 6);
$removed = $c->splice(1, 2, [99]); // вырезанное — новой коллекцией
$c->each(fn ($v) => $v === 3 ? false : process($v)); // false прерывает обход
$c->tap(fn ($col) => logger()->debug('size', [$col->count()]))
->when($withDiscount, fn ($col) => $col->map($applyDiscount))
->whenEmpty(fn ($col) => $col->push($default));
$total = $c->pipe(fn ($col) => $col->sum());- Каждая ловушка type juggling закрыта на уровне библиотеки, а не код-ревью.
- Мутанты и границы поведения зафиксированы: 100 % покрытие, Infection MSI 100 %.
- Наследование поддержано контрактом protected-хелперов (см. тесты
ExtensibilityTest).
- Нестрогих вариантов нет намеренно: код, рассчитывающий на
'1' == 1, придётся привести к явным типам (это считается достоинством).
- Пропускать недоверенный JSON только через
fromJsonс разумным лимитом глубины. - Проверки прав и идентификаторов — только строгими методами (они здесь все строгие).
- Приводить типы «на глаз» перед
contains/whereIn— приводите явно и осознанно. - Ловить
InvalidJsonExceptionи продолжать с пустой коллекцией без логирования — fail-safe не означает «молча проглотить».
CloudCastle Collection · · PHP 8.1+
GitHub · Packagist · Releases · Discussions
Email · Telegram · VK · Сетка · 💜 Поддержать проект
Исходники Wiki — каталог wiki/ в репозитории (синхронизация через GitHub Actions)