A robust, production-ready implementation of the Circuit Breaker pattern for PHP. Protect your microservices from cascading failures with configurable thresholds, multiple storage backends, an event system, and manual override capabilities.
stateDiagram-v2
[*] --> Closed
Closed --> Open : Failures ≥ threshold
Open --> HalfOpen : Timeout expires
HalfOpen --> Closed : Successes ≥ threshold
HalfOpen --> Open : Any failure
| State | Description |
|---|---|
| Closed | Normal operation. Requests pass through. Failures are counted. |
| Open | Circuit is tripped. All requests are rejected immediately. |
| Half-Open | Recovery probe. Limited requests are allowed to test if the service has recovered. |
composer require gabrielanhaia/php-circuit-breaker:^3.0Install only what you need:
# For Redis storage
# Requires ext-redis PHP extension
# For PSR-16 (SimpleCache) storage
composer require psr/simple-cache
# For PSR-6 (Cache) storage
composer require psr/cache
# For PSR-14 event dispatcher bridge
composer require psr/event-dispatcheruse GabrielAnhaia\PhpCircuitBreaker\CircuitBreaker;
use GabrielAnhaia\PhpCircuitBreaker\CircuitBreakerConfig;
use GabrielAnhaia\PhpCircuitBreaker\Storage\InMemoryStorage;
$storage = new InMemoryStorage();
$config = new CircuitBreakerConfig(
failureThreshold: 5,
openTimeout: 30,
);
$cb = new CircuitBreaker($storage, $config);
$service = 'payment-api';
if (!$cb->canPass($service)) {
// Circuit is open — use fallback
return cachedResponse();
}
try {
$result = callPaymentApi();
$cb->recordSuccess($service);
return $result;
} catch (\Throwable $e) {
$cb->recordFailure($service);
return cachedResponse();
}- Multiple storage backends — InMemory, Redis, APCu, Memcached, PSR-6, PSR-16
- Success threshold — require N consecutive successes before closing a half-open circuit
- Event system — react to state changes with listeners; optional PSR-14 bridge
- Manual override — force circuits open/closed for maintenance windows or testing
- State inspection — query effective circuit state at any time
- Immutable config — type-safe
CircuitBreakerConfigvalue object - Zero required extensions — only
ext-redis,ext-apcu,ext-memcachedneeded if you use those adapters - PHPStan level max — fully statically analyzed
- PHP 8.1+ — uses native enums, readonly properties, and named arguments
| Topic | Description |
|---|---|
| Configuration | Config object, parameter table, exception mode |
| Storage Adapters | All 6 adapters, key scheme, comparison table |
| Event System | Events, sequence diagram, SimpleEventDispatcher, PSR-14 bridge |
| Manual Override | forceState(), clearOverride(), state inspection |
| Architecture | Class diagram, directory structure, request flow |
See UPGRADE-3.0.md for a detailed migration guide.
| v2 | v3 |
|---|---|
CircuitStateEnum |
CircuitState (backing value 'close' → 'closed') |
CircuitBreakerAdapter (abstract class) |
CircuitBreakerStorageInterface |
new CircuitBreaker($adapter, $settings) |
new CircuitBreaker($storage, $config) |
Alert interface |
Event listeners |
AdapterException |
StorageException |
CircuitException |
OpenCircuitException |
ext-redis required |
ext-redis optional (suggested) |
$cb->failed($service)→ use$cb->recordFailure($service)$cb->succeed($service)→ use$cb->recordSuccess($service)
# Install dependencies
composer install
# Run tests
composer test # All tests
vendor/bin/phpunit --testsuite Unit # Unit tests only
vendor/bin/phpunit --testsuite Integration # Integration tests only
# Static analysis
composer phpstan
# Code style
composer cs-check # Check for violations
composer cs-fix # Auto-fix violationsGitHub Actions runs on PHP 8.1, 8.2, 8.3, 8.4 with three jobs:
- Tests — unit + integration (with Redis service)
- Static Analysis — PHPStan level max
- Code Style — PHP-CS-Fixer (PER-CS + PHP 8.1 migration)
If this library helps you, consider buying me a coffee:
MIT — see LICENSE for details.
Created by Gabriel Anhaia | Buy Me a Coffee