YACO (Yet Another COmpiler) 是一个基于入口定义生成 PHP 容器的 PHP 工具。

v1.0.0 2016-03-01 17:08 UTC

This package is auto-updated.

Last update: 2024-09-06 23:22:32 UTC


README

Scrutinizer Code Quality Build Status Coverage Status

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 的类。它们提供要由编译器编译的容器定义列表。