fas / di
快速且简单的依赖注入
0.4.5
2021-07-17 06:27 UTC
Requires
- php: >=7.4.0
- fas/autowire: ^0.2
- fas/exportable: ^0.2
- ocramius/proxy-manager: ^2.11
- opis/closure: ^3.6
- psr/container: ^1.0 || ^2.0
- psr/log: ^1.1
Requires (Dev)
- phpmd/phpmd: ^2.10
- phpunit/phpunit: ^9
- squizlabs/php_codesniffer: ^3.6
Provides
README
安装
composer require fas/di
使用
创建容器
// Brand new container $container = new Container; // Load compiled container if present $container = Container::load('/tmp/container.php');
添加依赖
// ->set(entryName, entryName | callback | null) // (singleton by default) $container->set(LoggerInterface::class, 'some_container_entry'); // abstract factory $container->set(LoggerInterface::class, 'some_container_entry')->factory(); // lazy $container->set(LoggerInterface::class, 'some_container_entry')->lazy(LoggerInterface::class); // lazy abstract factory $container->set(LoggerInterface::class, 'some_container_entry') ->lazy(LoggerInterface::class) ->factory(); // shorthands $container->singleton(LoggerInterface::class, 'some_container_entry'); $container->factory(LoggerInterface::class, 'some_container_entry'); $container->lazy(LoggerInterface::class, 'some_container_entry'); // If entry MyLogger::class does not exist in the container, // The class MyLogger::class will be instantiated. $container->singleton(LoggerInterface::class, MyLogger::class); // Custom factory method $container->singleton(LoggerInterface::class, function () { return new MyLogger; }); // Any callable will do $container->singleton(LoggerInterface::class, [MyLoggerFactory::class, 'create']);
抽象工厂。在每次调用 ->get() 时将解析
// ->factory(entryName, entryName | callback | null) $container->factory(MyLogger::class); // abstract factory shorthand $logger1 = $container->get(MyLogger::class); // will create new object $logger2 = $container->get(MyLogger::class); // will create new object
延迟解析。在使用前不会解析。(虚拟代理)
// ->lazy(entryName, entryName | callback | null) $container->lazy(MyLogger::class); // Lazy shorthand // make anything lazy $container->set('myentry', [MyFactory::class, 'create']) ->lazy(LoggerInterface::class);
混合匹配,任意组合
$container->factory(MyLogger::class)->lazy();
相当于
$container->lazy(MyLogger::class)->factory();
性能
// Use cached virtual proxies (lazy), and write cache if missing $container->enableProxyCache('/tmp/proxies'); // Generate a class containing proper methods for registered entries. // This can be used afterwards to avoid a lot of reflection when resolving entries. $container->save('/tmp/container.php');
配方
全自动缓存容器和代理
利用缓存的简单方式。
请注意,一旦缓存被写入,必须手动删除以更新。这种设置通常在开发中不是非常有用。
$container = Container::load("/tmp/container.php"); if (!$container) { $container = new Container; $container->singleton(LoggerInterface::class, MyLogger::class); $container->save('/tmp/container.php'); } $container->enableProxyCache("/tmp/proxies"); // Container ready for use
生成编译容器
这可以在构建阶段的启动过程中用于编译脚本。
$container = new Container; // ... populate container here $entries = $container->save("/tmp/container.php"); print "-----------------\nCompiled " . count($entries) . " entries\n-----------------\n"; print implode("\n", $entries) . "\n\n";
通用示例
使用配置、容器和路由的通用示例。
<?php require __DIR__ . '/../vendor/autoload.php'; use App\ContainerFactory; use App\RouterFactory; use Fas\DI\Container; use Fas\Configuration\DotNotation; use Fas\Configuration\YamlLoader; use Fas\Routing\Router; use Laminas\Diactoros\ResponseFactory; use Laminas\Diactoros\ServerRequestFactory; $configFile = getenv('CONFIG_FILE') ?: '/app/config.yaml'; try { // Setup configuration, container and router $configuration = FileCache::load('/tmp/config.cache.php') ?? new DotNotation(YamlLoader::loadWithOverrides($configFile)); $container = Container::load('/tmp/container.cache.php') ?? ContainerFactory::create($configuration); $router = Router::load('/tmp/router.cache.php') ?? RouterFactory::create($container); // Handle actual request $request = ServerRequestFactory::fromGlobals(); $response = $router->handle($request); } catch (Throwable $e) { $code = $e instanceof HttpException ? $e->getCode() : 500; $response = (new ResponseFactory)->createResponse($code, $e->getMessage()); $response->getBody()->write('<pre>' . (string) $e . '</pre>'); } finally { (new SapiEmitter)->emit($response); }
通用编译器示例
上面示例的编译器示例
<?php require __DIR__ . '/../vendor/autoload.php'; use App\ContainerFactory; use App\RouterFactory; use Fas\DI\Container; use Fas\Configuration\DotNotation; use Fas\Configuration\YamlLoader; use Fas\Routing\Router; use Laminas\Diactoros\ResponseFactory; use Laminas\Diactoros\ServerRequestFactory; $configFile = getenv('CONFIG_FILE') ?: '/app/config.yaml'; // Compile config $configuration = new DotNotation(YamlLoader::loadWithOverrides($configFile)); FileCache::save('/tmp/config.cache.php', $configuration); // Compile container $container = ContainerFactory::create($configuration); $entries = $container->save('/tmp/container.cache.php'); print "-----------------\nBuilt " . count($entries) . " entries\n-----------------\n" . implode("\n", $entries) . "\n-----------------\n"; // Compile routes $router = RouterFactory::create($container); $router->save('/tmp/router.cache.php');