在PHP中键入安全通用装饰器

我想创建一个类型安全的通用日志记录
decorator.

我有一些repositories(接口),并且每个都需要一个装饰器来捕获它们可能抛出的异常,将它们传递给LoggerInterface的实例然后重新抛出它们.可以为每个装饰器创建一个专用的装饰器和测试,虽然这非常麻烦(尤其是测试很好),而我宁愿避免.

使用__call创建更通用的装饰器是我想到的第一种方法.但是,这会导致对象实例无法实现其装饰的存储库接口.这在我的项目中是不行的.有没有办法告诉PHP它确实实现了这个界面,比如使用一些魔法reflection

我在stackoverflow上读到了“how to implement a decorator in PHP?”和“Best way to implement a decorator pattern for method result caching in PHP”,两者都概述了专用方法和通用方法,但两者都未提供以类型安全方式执行通用方法的指示.自那些问题发布以来已经过了一段时间,所以可能情况发生了变化.我正在使用PHP 7,如果需要可以使用PHP 7.1.

PHPUnit_MockObject允许通过PHPUnit中熟悉的getMock方法调用的相同代码构建实现接口的对象.这可以是通用装饰器的基础.但是,这需要在生产代码中使用模拟库.此外,这个库internally uses eval完成了它的工作.这使我的项目失去了资格.

最佳答案 另一种方法是在运行时动态创建修饰的类.不幸的是
PHP doesn’t allow this out of the box.如果
runkit扩展名不是一个选项,你可以模仿
Doctrine ORM的作用:让DecoratorFactory执行以下步骤:

>在原始类上使用Reflection来获取所有接口及其方法,
>使用包含实现所有接口的修饰代理类的PHP代码生成文件
>包括生成的代理类
>使用原始类实例化生成的代理类并返回代理类.

请参阅http://www.doctrine-project.org/api/orm/2.4/source-class-Doctrine.ORM.Tools.EntityGenerator.html的示例

点赞