maplephp/container

支持PSR-11的全功能容器、工厂和依赖注入器。

v1.1.2 2023-12-13 19:25 UTC

This package is auto-updated.

Last update: 2024-09-16 17:08:48 UTC


README

为MaplePHP框架构建的PSR容器

容器、工厂和依赖注入器通过减少对象之间的耦合,集中管理依赖关系,可以帮助您使PHP代码更具可维护性、灵活性和可测试性。

容器

容器允许您轻松创建和检索应用程序中所需的对象。

use MaplePHP\Container\Container;
$container = new Container();
$container->set("YourClass", \YourNamespace\To\YourClass::class); // Bind "YourClass" to container and dependency injector
$yourClass = $container->get("YourClass")->get(); // Will return "YourClass"
//$yourClass->yourClassMehthod();

如果"YourClass"的构造函数包含未解决的类参数,依赖注入器将尝试自动为您找到它们。有关详细信息,请参阅"依赖注入器"部分。

工厂

工厂可用于创建对象的新实例,而不是在您的代码中直接实例化它们。

$container->factory("factoryKey", function() {
    $a = new TestClassA();
    $b = new TestClassB();
    return new TestClassC($a, $b);
});
echo $container->get("factoryKey"); // Will return TestClassC

依赖注入器

依赖注入是一种管理应用程序中对象之间依赖关系的技术。在实例化对象时,您可以将它们作为依赖项传递,而不是直接在代码中创建对象。这使得您的代码更模块化,更容易测试,因为您可以轻松地用模拟对象或其他实现替换依赖项。

您可以使用依赖注入器就像创建任何其他容器一样,只要您不添加参数或尝试访问方法,如果这样做,它将自动禁用依赖注入器。这样设计是因为它会加载所有类自引用到无限循环中。

请看这个例子

$container->set("YourClass", \YourNamespace\To\YourClass::class);
$testService = $container->get("YourClass");
echo $testService->start();

上面的代码将加载YourClass并自动初始化类Test

namespace YourNamespace\To;

use YourNamespace\ToTestClasses\Test;

class YourClass {
    
    private $test;

    // Dependency injector will auto load "Test" class and the "Test" classes and so on.
    function __construct(Test $test) {
        $this->test = $test;
    }

    function start() {
        return $this->test->get("This is the start page");
    }
    
}

事件处理器

初始化

use MaplePHP\Container\EventHandler;

示例 1 - (调用)

$logger = new EventHandler();
$logger->addHandler(new Logger());
$logger->addEvent(function() {
    var_dump("Executed in conjunction with logger every method");
    // You could add a mail function that will send log message to you,
});
echo $logger->error("A error message to log");
// Will log message AND execute the event

示例 2 - (绑定到方法)

$logger = new EventHandler();
$logger->addHandler(new Logger(), ["emergency", "alert", "critical"]);
$logger->addEvent(function() {
    var_dump("Executed in conjunction with logger event method");
    // You could add a mail function that will send log message to you,
});
echo $logger->error("A error message to log");
// Will only log message
echo $logger->alert("A error message to log");
// Will log message AND execute the event

示例 3 - (添加服务到处理器)

将命名空间设置为EventInterface

use MaplePHP\Container\Interfaces\EventInterface;

然后扩展实现接口的类EventInterface并向该类添加方法resolve。以下我使用"匿名函数"作为示例,仅为了展示需要实现EventInterface,您可以使用常规类。

$callableFunction = new class implements EventInterface {

    public function someMethod(string $what): string
    {
        return "Hello {$what}!";
    }

    // Resolve method will be executed in conjunction 
    // with logger event method
    public function resolve(): void
    {
        var_dump($this->someMethod("world"));
    }
};

$logger = new EventHandler();
$logger->addHandler(new Logger(), ["emergency", "alert", "critical"]);
$logger->addEvent(function() {
    var_dump("Executed in conjunction with logger event method");
    // You could add a mail function that will send log message to you,
});
echo $logger->error("A error message to log");
// Will only log message
echo $logger->alert("A error message to log");
// Will log message AND execute the event