InitPHP Container is a small PSR-11 container. It stores entries you register and can also build classes for you automatically through reflection. This guide covers installation and the two methods that make up the public API: get() and has(), plus the set() registration method.
composer require initphp/containerRequires PHP 8.1+ and psr/container ^2.0 (pulled in automatically).
require_once 'vendor/autoload.php';
use InitPHP\Container\Container;
$container = new Container();The container takes no constructor arguments and holds no global state. Create as many as you need.
The container implements Psr\Container\ContainerInterface, which defines two methods:
public function get(string $id): mixed;
public function has(string $id): bool;On top of those, the container adds one registration method:
public function set(string $id, mixed $concrete = null): void;// Store a value.
$container->set('app.name', 'InitPHP');
// Store an object.
$container->set('clock', new DateTimeImmutable());
// Register a class to be built on demand.
$container->set(App\Service::class);
// Bind an identifier to a class name.
$container->set(App\LoggerInterface::class, App\FileLogger::class);
// Register a lazy factory.
$container->set('pdo', fn () => new PDO('sqlite::memory:'));When the second argument is omitted, the identifier itself becomes the definition. Calling set() again with the same identifier replaces the previous definition and clears any cached instance.
$name = $container->get('app.name'); // 'InitPHP'
$service = $container->get(App\Service::class);If the identifier was never registered but is an existing class name, the container autowires it. If it is neither, a NotFoundException is thrown. See Autowiring.
$container->has('app.name'); // true once registered
$container->has(App\Service::class); // true: it is an autowirable class
$container->has('not-registered'); // falsehas() returns true whenever get() would not throw a NotFoundException.
Every entry the container resolves is cached and reused:
$a = $container->get(App\Service::class);
$b = $container->get(App\Service::class);
$a === $b; // trueThis makes the container behave as a registry of shared instances. If you need a fresh object every time, build it yourself inside a closure and create the instance there explicitly, or instantiate the class directly without the container.
- Autowiring — how constructor dependencies are resolved.
- Binding & Factories — interfaces, closures and values.
- Exceptions & Error Handling — what can go wrong and why.
- Limitations — what this container intentionally does not do.