lingualeo/php-servaxle

Servaxle 是一个快速的 PHP 依赖注入容器

2.2.0 2016-02-22 09:30 UTC

README

Servaxle 是一个快速的 PHP 依赖注入容器。

如何使用它?

依赖注入容器以作用域的形式呈现。该作用域通过反射发现依赖项。仅解析命名空间中的类。

namespace Tutorial;

class Foo
{
}

class Bar
{
    public function __construct(Foo $foo)
    {
    }
}

$scope = new \LinguaLeo\DI\Scope([
    'bar' => Bar::class
]);

$scope->bar; // instance of Tutorial\Bar class

您可以定义通用接口实现。

namespace Tutorial;

interface AnimalInterface {}

class Dog implements AnimalInterface {}

class Cat implements AnimalInterface {}

class Home
{
    public function __construct(AnimalInterface $animal)
    {
    }
}

$scope = new \LinguaLeo\DI\Scope([
    'home' => Home::class,
    AnimalInterface::class => Dog::class
]);

$scope->home; // instanse of Tutorial\Home class with Tutorial\Dog object injection

但是您也可以将简单数据类型放入作用域中。

$scope = new LinguaLeo\DI\Scope([
    'user' => 'root'
]);

$scope->getValue('user'); // "root"

您还可以定义一个常量。类命名空间中的常量也将被处理。

$scope = new LinguaLeo\DI\Scope([
    'max' => 'PHP_INT_MAX'
]);

$scope->max; // 9223372036854775807 (in 64 bit OS)

符号链接

您可以为另一个变量定义一个符号链接。

$scope = new LinguaLeo\DI\Scope([
    'super' => 'admin',
    '@user' => 'super',
    'member' => '@user'
]);

$scope->getValue('member'); // "admin" as @user -> super -> admin

变量

您可以在不进行符号链接查找的情况下定义目标变量。

$scope = new LinguaLeo\DI\Scope([
    'super' => 'admin',
    'member' => '$super'
]);

$scope->getValue('member'); // "admin"

缓存

每次您调用 getValue 方法时,作用域都会解析依赖项。但如果您作为属性访问值,作用域将缓存它。

$scope = new LinguaLeo\DI\Scope([
    'now' => function () {
        return uniqid();
    }
]);

$scope->getValue('now') === $scope->getValue('now'); // false
$scope->now === $scope->now; // true

工厂设计模式

您可以创建自己的工厂来自定义初始化。不需要特殊的接口或类。只需使用魔法!

namespace Tutorial;

class RedisFactory
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function __invoke()
    {
        $redis = new \Redis();
        $redis->connect($this->host);
        return $redis;
    }
}

$scope = new \LinguaLeo\DI\Scope([
    'redis' => RedisFactory::class,
    'redis.host' => '192.168.1.1'
]);

$scope->redis; // instance of \Redis class

编译

对于复杂的依赖项树,我们创建了将其编译成 PHP 脚本的编译过程。

namespace Tutorial;

// define classes
class Foo {}

class Bar
{
    public function __construct(Foo $foo) {}
}

class Baz
{
    public function __construct(Bar $bar) {}
}

// compiles a tree
$script = \LinguaLeo\DI\Scope::compile([
    'baz' => Baz::class
]);

// put into PHP file
file_put_contents('cache.php', '<?php return '.$script.';');

// init a scope from file
$scope = new \LinguaLeo\DI\Scope(include 'cache.php');

$scope->baz; // instance of Tutorial\Baz class

不可变作用域

如果您不需要自动反射,则应实例化 ImmutableScope 类。这对于早期编译的依赖项很有用。

$scope = new LinguaLeo\DI\ImmutableScope(include 'cache.php');

来源: https://github.com/LinguaLeo/php-servaxle