c01l/phpdecorator

phpdecorator 库可以用来包装对象和类的函数,添加额外功能。这是与 Python 装饰器可以比较的功能。

1.2.0 2021-12-30 01:00 UTC

This package is auto-updated.

Last update: 2024-09-29 05:43:19 UTC


README

phpdecorator 库可以用来包装对象和类的函数,添加额外功能。这是与 Python 装饰器可以比较的功能。

如何创建自己的装饰器?

  1. 声明一个可以放置在库提供的 Decorator 基类扩展方法上的属性。
  2. 实现返回一个函数的 wrap 函数,该函数将代替原始函数被调用。
  3. 使用 call_user_func_arrayfunc_get_args 一起调用原始函数。
#[\Attribute(\Attribute::TARGET_METHOD)]
class LoggingDecorator extends \C01l\PhpDecorator\Decorator
{
    public function wrap(callable $func): callable
    {
        return function () use ($func) {
            /** @var Logger $logger */
            $logger = $this->getContainer()->get(Logger::class);
            $logger->log("Started");
            $ret = call_user_func_array($func, func_get_args());
            $logger->log("Ended");
            return $ret;
        };
    }
}

使用装饰器

只需在类上注释相关函数。

class SomeClass
{
    #[LoggingDecorator]
    public function foo(int $bar): int
    {
        return $bar;
    }
}

如果对象通过库传递,则只有功能会被替换。

$decoratorManager = new DecoratorManager();

$obj = $decoratorManager->instantiate(SomeClass::class); // only possible for classes with a parameter-less constructor!
// OR
$obj = new SomeClass();
$obj = $decoratorManager->decorate($obj); // creates a proxy object (do not use the original reference of the object!)

高级用法

将依赖项容器传递给装饰器

您可以向 DecoratorManager 提供一个容器,该容器将传递给每个将被实例化的 Decorator

$container = /* use some PSR-11 container */
$decoratorManager = new DecoratorManager(container: $container)

在装饰器中,您可以使用 $this->getContainer() 获取容器。

缓存生成的类

如果您在大量类上使用此库,可能适合使用类缓存。这样类只生成一次,可以由运行时进行优化。

只需提供一个文件夹的路径,您的运行时允许在该文件夹中读取和写入文件。

$decoratorManager = new DecoratorManager(classCachePath: "/path/to/cache/");