cloud-castle / idempotency
Production-ready PHP 8.1+ package (CloudCastle Idempotency).
Requires
- php: >=8.1
- psr/simple-cache: ^3.0
Requires (Dev)
- deptrac/deptrac: ^3.0 || ^4.0
- ergebnis/composer-normalize: ^2.45
- friendsofphp/php-cs-fixer: ^3.75
- icanhazstring/composer-unused: ^0.9
- infection/infection: ^0.29 || ^0.33
- php-parallel-lint/php-parallel-lint: ^1.4
- phpmd/phpmd: ^2.15
- phpstan/extension-installer: ^1.4
- phpstan/phpstan: ^1.12 || ^2.1
- phpstan/phpstan-deprecation-rules: ^1.2 || ^2.0
- phpstan/phpstan-phpunit: ^1.4 || ^2.0
- phpstan/phpstan-strict-rules: ^1.6 || ^2.0
- phpunit/phpunit: ^10.5 || ^11.5
- psalm/plugin-phpunit: ^0.19 || ^0.20
- rector/rector: ^1.2 || ^2.0
- roave/security-advisories: dev-latest
- squizlabs/php_codesniffer: ^3.12 || ^4.0
- vimeo/psalm: ^6.0
- webmozart/assert: ^1.11
Suggests
- cloud-castle/cache: PSR-16 хранилище для сохранения результатов идемпотентных операций
This package is auto-updated.
Last update: 2026-07-29 13:10:16 UTC
README
🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano
CloudCastle Idempotency
Идемпотентное выполнение операций поверх любого PSR-16 хранилища: результат первого выполнения сохраняется и возвращается при повторах. Повтор ключа с иными данными отвергается как конфликт — защита от двойной обработки платежей.
Установка
composer require cloud-castle/idempotency
Требуется PHP 8.1+ и любая PSR-16 реализация (например, cloud-castle/cache).
Быстрый старт
<?php
use CloudCastle\Idempotency\Exception\IdempotencyConflictException;
use CloudCastle\Idempotency\IdempotentExecutor;
// $cache — любая PSR-16 реализация; ttl — срок хранения результата.
$executor = new IdempotentExecutor($cache, ttl: 86400);
$key = $request->header('Idempotency-Key'); // ключ от клиента
$fingerprint = hash('sha256', $request->rawBody()); // отпечаток данных
// Операция выполнится один раз; повторы вернут сохранённый результат.
$payment = $executor->execute($key, static fn () => $gateway->charge($amount), $fingerprint);
// Тот же ключ с ДРУГИМИ данными → IdempotencyConflictException.
Возможности
- Выполнение ровно один раз — операция с данным ключом исполняется однажды; при повторах возвращается сохранённый результат, операция не запускается заново.
- Контроль отпечатка — повтор ключа с иным отпечатком исходных данных
отвергается
IdempotencyConflictException(ключ не должен переиспользоваться с другими данными — критично для операций с деньгами). - Любое PSR-16 хранилище — работает с любой реализацией кэша; ключи нормализуются (SHA-256) и изолируются префиксом.
- Настраиваемый срок хранения результата (
ttl, по умолчанию сутки). - Произвольный тип результата — сохраняется и возвращается как есть.
Безопасность
Идемпотентность — базовая защита от двойного списания при повторной отправке
запроса (ретрай сети, двойной клик). Отпечаток данных не даёт злоумышленнику или
ошибке переиспользовать чужой/старый ключ с новыми параметрами. Для строгой
защиты от гонки двух одновременных запросов с одним ключом дополните внешней
блокировкой (cloud-castle/lock).
Сравнение с аналогами
| Возможность | idempotency | laravel-idempotency | stripe (SDK) | symfony/lock (косвенно) | ramsey/idempotency | самописное |
|---|---|---|---|---|---|---|
| Выполнение один раз | ✅ | ✅ | ✅ | ⚠️ | ✅ | ⚠️ |
| Конфликт по отпечатку данных | 🏆 ✅ | ❌ | ✅ | ❌ | ⚠️ | ❌ |
| Любое PSR-16 хранилище | 🏆 ✅ | ⚠️ | ❌ | ⚠️ | ⚠️ | ⚠️ |
| Без привязки к фреймворку | 🏆 ✅ | ❌ | ⚠️ | ✅ | ✅ | ✅ |
| Runtime-зависимостей | 🏆 1 (PSR-16) | много | много | 1 | 2+ | 0 |
Когда применять. idempotency уместен для серверных операций, которые нельзя
выполнять дважды: платежи, создание заказов, отправка уведомлений. Даёт ядро
«выполнить один раз» без привязки к фреймворку. Если нужен полный HTTP-middleware
идемпотентности с автоматическим перехватом заголовка — соберите его поверх этого
пакета и cloud-castle/middleware.
Разработка
composer install
composer check # линтеры + статический анализ + тесты
composer fix # автоисправления (Rector, PHP CS Fixer, PHPCBF)
composer ci # полный CI-пайплайн локально
Полный список команд с описаниями: composer run-script --list.
Документация
- Репозиторий: https://gitverse.ru/cloud-castle/idempotency
- История изменений: CHANGELOG.md
- Как внести вклад: CONTRIBUTING.md
- Кодекс поведения: CODE_OF_CONDUCT.md
- Политика безопасности: SECURITY.md
Лицензия
MIT © CloudCastle (alex-4-17@yandex.ru)
🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano