Lightweight PSR-11 Container implementation without magic.
- PSR-11 compliant (
Psr\Container\ContainerInterface) - Simple configuration via PHP arrays:
services– prebuilt instancesfactories– callables or factory classesinvokables– classes instantiated without argumentsaliases– alternate identifiers for a classshared– control which entries are singletons (by default none)
- No magic, no global state, no hidden side effects
- No runtime dependencies, tiny footprint
composer require marek-baron/container<?php
use MarekBaron\Container\Container;
use Psr\Container\ContainerInterface;
// Examples
class Logger
{
public function __construct(
private readonly array $config,
) {}
public function log(string $message): void
{
echo sprintf(
'[%s] %s | app=%s%s',
date('c'),
$message,
$this->config['app_name'] ?? 'unknown',
PHP_EOL
);
}
}
class LoggerFactory
{
public function __invoke(ContainerInterface $container, string $id): Logger
{
// pull config or other dependencies from the container here
$config = $container->get('config');
return new Logger($config);
}
}
class UserService
{
public function __construct(
private Logger $logger,
) {}
public function createUser(string $email): void
{
// create user...
$this->logger->log(sprintf('Created user %s', $email));
}
}
class SomeSimpleClass
{
public function foo(): string
{
return 'bar';
}
}
$config = [
'services' => [
'config' => [
'app_name' => 'My App',
],
],
'factories' => [
Logger::class => LoggerFactory::class,
UserService::class => static function (ContainerInterface $container): UserService {
return new UserService($container->get(Logger::class));
},
],
'invokables' => [
SomeSimpleClass::class => SomeSimpleClass::class,
],
'aliases' => [
'logger' => Logger::class,
'user_service' => UserService::class,
],
'shared' => [
Logger::class => true, // always the same instance (singleton)
UserService::class => false, // new instance on each get()
],
];
$container = new Container($config);
// Usage examples:
$logger = $container->get(Logger::class); // resolved via factory
$logger = $container->get('logger'); // resolved via alias
$simpleClass = $container->get(SomeSimpleClass::class); // resolved via invokable
$service = $container->get('user_service'); // resolved via alias + factory
$service->createUser('user@example.com');
var_dump($container->has('logger')); // true
var_dump($container->has('unknown_service')); // falseA Dockerfile and docker-compose.yml are included for local development. They are excluded from Packagist via .gitattributes.
docker compose run --rm container-dev composer checkMIT License © Marek Baron