Installation & Requirements
Winter DI has a single runtime dependency and needs PHP 8.4. There are no required
extensions — Swoole is optional and only affects the request scope.
System requirements
- PHP version — 8.4 or higher. The
#[Lazy]attribute injects a native PHP 8.4 lazy proxy (ReflectionClass::newLazyProxy()), which does not exist on earlier versions. psr/container—^2.0. Installed automatically; the container implements itsContainerInterface.- Operating system — portable. No POSIX or platform-specific dependency in the core.
Check your PHP version with php -v.
composer require flytachi/winter-diOptional: Swoole
ext-swoole is optional. It matters only for the request scope: under Swoole, a
request-scoped instance is stored in the coroutine context so each concurrent request gets
its own copy. Without Swoole (PHP-FPM or CLI) the request scope behaves like singleton —
one process handles one request, so a process-level cache is already correct.
# Check if Swoole is loaded
php -m | grep swooleYou do not need Swoole to use the container, autowiring, attributes, or the other two scopes. See Request scope & Swoole for details.
Bootstrap
Initialise the container once at application startup. Container::init() creates the
instance and stores it as the process-wide singleton so it can be reached anywhere via
Container::getInstance().
<?php
require 'vendor/autoload.php';
use Flytachi\Winter\DI\Container;
use Flytachi\Winter\DI\Scanner;
use Flytachi\Winter\DI\Collector\DICollector;
// 1. Create the container
$container = Container::init();
// 2. Auto-register annotated classes (#[Singleton], #[Request], #[Transient])
Scanner::run(__DIR__ . '/src', cache: __DIR__ . '/var/cache/di.php')
->collect(new DICollector($container))
->execute();
// 3. Register interface bindings and factories
$container->register(AppServiceProvider::class);The three steps are independent — you can skip the Scanner step and register everything
manually, or skip providers if you only rely on attributes and autowiring.
What each step gives you
Step 2 (Scanner + DICollector) discovers classes carrying a scope attribute and binds
them — see Scanning & autodiscovery. Step 3
(ServiceProvider) is where interface → implementation mappings and factory closures live —
see Service providers.
Next steps
- Quickstart — resolve your first service in five minutes
- Mental model — how autowiring and scopes fit together
- API reference — every container method