graham-campbell/manager
Adds a reusable “manager” layer for Laravel packages and apps, helping you build driver-based services (create, cache, and resolve drivers) with a consistent API. Supports Laravel 8–13 and PHP 7.4–8.5.
Strengths:
CacheManager, DatabaseManager), reducing cognitive load for developers familiar with the ecosystem.Manager::extend('stripe', fn() => new StripeClient())), ideal for SaaS multi-tenancy or plugin architectures.UserManager, OrderManager), accelerating MVP development.Weaknesses:
ServiceProvider or custom logic.disconnect() calls may leak resources if not handled (e.g., in long-running CLI jobs).ServiceProvider bindings (e.g., bind('manager', fn() => new CustomManager())).ManagerInterface) simplify unit/integration tests for connection-heavy logic.| Risk Area | Assessment | Mitigation Strategy |
|---|---|---|
| Version Compatibility | Supports Laravel 8–13 but no backward compatibility for <L8. | Lock to a specific minor version (e.g., ^5.3) and test against target Laravel. |
| Connection Leaks | No built-in TTL for connections (e.g., HTTP clients, DB pools). | Implement a Manager::flush() method or use Laravel’s Event::dispatch() to clean up. |
| Performance Overhead | Connection pooling adds memory overhead for high-concurrency apps. | Benchmark with memory_get_usage() and consider stateless connections (e.g., HTTP clients). |
| Security | No built-in authentication validation for dynamic extensions. | Validate extend() callbacks via Laravel Policies or custom middleware. |
| Adoption Friction | Requires refactoring existing manager classes to extend AbstractManager. |
Start with a single pilot service (e.g., NotificationManager) before full rollout. |
Use Case Alignment:
Team Readiness:
CacheManager)?Long-Term Maintenance:
Alternatives:
Manager trait (e.g., in Illuminate\Support\Manager) suffice, or does this package’s simplicity justify the dependency?php-http/guzzle-adapter) be better?S3Manager, TwilioManager) with a unified pattern.Manager::extend('payment', $tenant->paymentGateway)).| Phase | Action | Tools/Examples |
|---|---|---|
| Assessment | Audit existing managers (e.g., UserManager, PaymentGateway) for compatibility. |
grep -r "class.*Manager" in codebase. |
| Pilot | Refactor one non-critical manager (e.g., LogManager) to extend AbstractManager. |
Example: Laravel Flysystem. |
| Core Adoption | Replace 3+ managers with AbstractManager; test connection pooling. |
Use Manager::getConnections() to verify pooling works. |
| Extension | Add dynamic drivers (e.g., Manager::extend('analytics', fn() => new Mixpanel())). |
Configure via config/manager.php or environment variables. |
| Optimization | Benchmark memory/performance; add connection TTL if needed. | Use Laravel’s Event::dispatch('manager.connection.created') for hooks. |
^5.3 for stability).composer require graham-campbell/manager:^5.3 --dev
config/manager.php needed; use Laravel’s existing config (e.g., config/filesystems.php).AbstractManager:
class StorageManager extends AbstractManager
{
protected function createConnection(array $config): StorageConnector
{
return new S3Connector($config);
}
protected function getConfigName(): string
{
return 'filesystems';
}
}
$this->app->singleton('manager', fn() => new StorageManager());
$manager = app('manager');
$s3 = $manager->connection('s3')->put('file.txt', 'content');
// OR (dynamic method calls)
$manager->put('file.txt', 'content'); // Calls $manager->connection()->put()
connect()/disconnect() logic across managers.config/filesystems.php).Manager::getConnections() provides visibility into active connections.CacheManager.How can I help you explore Laravel packages today?