thecodingmachine / yaco
YACO (Yet Another COmpiler) 是一个基于入口定义生成 PHP 容器的 PHP 工具。
Requires
Requires (Dev)
- container-interop/definition-interop-tests: dev-master
- mnapoli/assembly: dev-master
- phpunit/phpunit: ~4.5
- satooshi/php-coveralls: dev-master
README
YACO - 另一个编译器
YACO (Yet Another COmpiler) 是一个 PHP 工具,它基于入口定义生成 PHP 容器。它与 definition-interop 的入口定义完全兼容。
安装
您可以通过 Composer 安装此软件包
{ "require": { "thecodingmachine/yaco": "^1.2" } }
该软件包遵循 SemVer 规范,并且次要版本之间将实现完全向后兼容。
使用方法
此软件包包含一个 Compiler
类。该类的目的是接收多个“入口定义”(如 definition-interop 中定义的)并将它们转换为一个实现 ContainerInterface
的 PHP 类。
use TheCodingMachine\Yaco\Compiler; $compiler = new Compiler(); // ... foreach ($definitions as $identifier => $definition) { /* @var $definition Interop\Container\Definition\DefinitionInterface */ $compiler->addDefinition($identifier, $definition); } // Let's dump the code of the My\Container class. file_put_contents("Container.php", $compiler->compile("My\\Container"));
现在,您可以使用以下代码实例化容器
$container = new My\Container(); $service = $container->get('a_service');
注意:Yaco 消耗 容器定义(实现 Interop\Container\Definition\DefinitionInterface
)。默认情况下,Yaco 不提供实现此接口的任何类。但是,您可以在类似 mnapoli/assembly 的软件包中找到此类类。
以下是使用 Yaco 和 Assembly 的完整示例
编译阶段
use TheCodingMachine\Yaco\Compiler; use function \Assembly\object; use function \Assembly\alias; $compiler = new Compiler(); $loggerDefinition = object('MyLogger') ->setConstructorArguments('warning') ->addMethodCall('setDebug', true); $compiler->addDefinition('logger', $loggerDefinition); // Let's dump the code of the My\Container class. file_put_contents("Container.php", $compiler->compile("My\\Container"));
使用方法
require_once('Container.php'); $container = new My\Container(); $logger = $container->get('logger');
注意:My\Container
类实现了 Interop\Container\ContainerInterface
。因此,它可以与任何兼容 container-interop 的框架一起使用。
服务提供者支持
此软件包支持 container-interop/service-provider 中定义的无容器服务提供者。
要注册服务提供者,您必须向编译器传递一个 TheCodingMachine\ServiceProvider\Registry
对象。
以下是一个示例
use TheCodingMachine\Yaco\Compiler; use TheCodingMachine\ServiceProvider\Registry; $registry = new Registry([ MyServiceProvider::class ]); // The registry is passed as first argument to the compiler. $compiler = new Compiler($registry); // Let's dump the code of the My\Container class. file_put_contents("MyContainer.php", $compiler->compile("MyContainer"));
重要!当您想使用编译后的容器时,必须传递包含相同服务提供者的注册表,并且顺序相同。
以下是由上述代码生成的容器的实例化
use TheCodingMachine\ServiceProvider\Registry; $registry = new Registry([ MyServiceProvider::class ]); // The registry is passed as first argument to the compiler. $container = new MyContainer($registry); $service = $container->get('a_service');
杂项
委托查找支持
由 Yaco 生成的容器支持 container-interop 的 “委托查找”功能。
如果您将容器作为生成的容器的第二个参数传递,则所有依赖项查找都将在该容器上执行,而不是在生成的容器上执行。
以下是一个示例
// $rootContainer is a composite container from the acclimate library $rootContainer = new Acclimate\CompositeContainer(); $myContainer = new MyContainer(null, $rootContainer); $rootContainer->addContainer($myContainer);
定义提供者
您可以直接使用 register
方法注册一个 定义提供者
use TheCodingMachine\Yaco\Compiler; $compiler = new Compiler(); // ... $compiler->register($definitionProvider); // Let's dump the code of the My\Container class. file_put_contents("Container.php", $compiler->compile("My\\Container"));
定义提供者是实现了 Interop\Container\Definition\DefinitionProviderInterface
的类。它们提供要由编译器编译的容器定义列表。