jdwx / iproxy
此包的最新版本(v0.0.2)没有提供许可证信息。
v0.0.2
2023-04-06 00:33 UTC
Requires
- php: ^8.0
- ext-ast: *
- ext-ctype: *
README
该工具会自动为给定的接口生成PHP代理特性代码。代理模式允许在不使用继承的情况下将功能添加到类中。当需要根据运行时情况进行交换的多个实现扩展接口时,这非常有用。
这是一个非常有限的“20%的努力换来80%的结果”的实现。它满足了我的需求,但存在已知限制,可能还有一些未知限制。
- (尚未)不支持DNF类型参数和返回类型。
- (尚未)不支持可变参数函数。
- (尚未)不支持参数默认值。
- 不支持继承自其他接口的接口。(这将非常具有挑战性。)
安装
通过composer
composer require jdwx/iproxy
此操作需要PHP AST扩展来运行,但生成的新的PHP源文件没有外部依赖。
使用方法
创建一个包含要代理的接口的文件(例如,IFoo.php)
<?php interface IFoo { public function bar() : baz; }
运行以下命令
YourPrompt$ vendor/bin/iproxy.php IFoo.php >FooProxy.php
这将创建一个包含实现接口的特质的文件(例如,FooProxy)
<?php trait TFooProxy { private IFoo $proxyFoo; public function bar() : baz { return $this->proxyFoo->bar(); } protected function setProxyFoo( IFoo $i_proxyFoo ) : void { $this->proxyFoo = $i_proxyFoo; } }
该特质将实现接口代理,并添加一个setProxy{Name}()
方法,可以从构造函数中用来设置代理目标。
将此特质添加到类中,就足以允许在类定义中添加“implements FooInterface”
<?php class DecoratedFoo implements IFoo { use TFooProxy; public function __construct( IFoo $i_foo ) { $this->setProxyFoo( $i_foo ); } public function alsoDoesQux() : void { // ... whatever ... } }
对于外部用户,DecoratedFoo将表现得像它继承了作为构造函数参数传入的任何IFoo实现类。
代理生成器将尝试保留原始文件中的namespace
、declare
和use
语句(但不包括use function
或use const
)。
如果接口名称的第一个字符是大写I,第二个字母也是大写,则将删除前面的I。如果接口名称中包含“Interface”,则将其删除。在所有情况下,将向特质名称添加一个大写T。