lighthouse / container
PSR-11 Dependency Injection Container for the Lighthouse framework
Installs: 11
Dependents: 1
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/lighthouse/container
Requires
- php: ^8.2
- psr/container: ^2.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^11.0
Provides
README
A PSR-11 compliant Dependency Injection Container for the Lighthouse framework.
Installation
composer require lighthouse/container
Requirements
- PHP 8.2 or higher
Features
- Full PSR-11 compliance
- Autowiring via reflection
- Manual bindings
- Singletons
- Factories
- Interface to implementation binding
- Method injection
- Circular dependency detection
Quick Start
Basic Autowiring
The container can automatically resolve class dependencies:
use Lighthouse\Container\Container; class Logger { public function log(string $message): void { echo $message; } } class UserService { public function __construct( private Logger $logger ) {} } $container = new Container(); // Automatically resolves Logger dependency $userService = $container->get(UserService::class);
Manual Bindings
Bind interfaces to implementations:
interface CacheInterface { public function get(string $key): mixed; } class RedisCache implements CacheInterface { public function get(string $key): mixed { // Redis implementation } } $container->bind(CacheInterface::class, RedisCache::class); $cache = $container->get(CacheInterface::class); // Returns instance of RedisCache
Closure Bindings
Use closures for complex instantiation:
$container->bind(Database::class, function (Container $c) { $config = $c->get(Config::class); return new Database( host: $config->get('db.host'), user: $config->get('db.user'), pass: $config->get('db.pass') ); });
Singletons
Register a binding that returns the same instance:
$container->singleton(Database::class, function (Container $c) { return new Database(/* ... */); }); $db1 = $container->get(Database::class); $db2 = $container->get(Database::class); // $db1 === $db2 (same instance)
Register Existing Instance
$logger = new Logger(); $container->instance(Logger::class, $logger); // Always returns the same $logger instance
Factories
Register a factory that creates a new instance each time:
$container->factory(RequestId::class, function () { return new RequestId(uniqid()); }); $id1 = $container->get(RequestId::class); // RequestId with unique id $id2 = $container->get(RequestId::class); // Different RequestId
Method Injection
Call methods with automatic dependency resolution:
class OrderController { public function store(OrderService $service, Validator $validator): Order { // ... } } $controller = new OrderController(); // Automatically resolves OrderService and Validator $result = $container->call($controller, 'store'); // With additional parameters $result = $container->call($controller, 'update', ['id' => 123]);
PSR-11 Methods
// Check if entry exists $container->has(Logger::class); // true/false // Get entry (throws NotFoundException if not found) $container->get(Logger::class);
Error Handling
The container throws PSR-11 compliant exceptions:
use Lighthouse\Container\Exception\NotFoundException; use Lighthouse\Container\Exception\ContainerException; try { $container->get('UnknownClass'); } catch (NotFoundException $e) { // Entry not found } catch (ContainerException $e) { // Error during resolution (circular dependency, etc.) }
Circular Dependency Detection
The container detects circular dependencies and throws a clear error:
class A { public function __construct(B $b) {} } class B { public function __construct(A $a) {} } $container->get(A::class); // Throws: ContainerException: Circular dependency detected while resolving "A"
API Reference
| Method | Description |
|---|---|
get(string $id) |
Resolve an entry (PSR-11) |
has(string $id) |
Check if entry exists (PSR-11) |
bind(string $id, mixed $concrete) |
Register a binding |
singleton(string $id, mixed $concrete) |
Register a shared binding |
instance(string $id, mixed $instance) |
Register an existing instance |
factory(string $id, callable $factory) |
Register a factory |
call(object|string $target, string $method, array $params) |
Call method with DI |
flush() |
Clear all bindings and instances |
getBindings() |
Get all registered binding IDs |
isShared(string $id) |
Check if binding is a singleton |
Testing
composer test
License
MIT License. See LICENSE for details.
Part of the Lighthouse Framework
This package is part of the Lighthouse Framework, an educational PHP framework designed to teach how modern frameworks work internally.