jdwx/iproxy

此包的最新版本(v0.0.2)没有提供许可证信息。

v0.0.2 2023-04-06 00:33 UTC

This package is auto-updated.

Last update: 2024-09-06 03:26:32 UTC


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实现类。

代理生成器将尝试保留原始文件中的namespacedeclareuse语句(但不包括use functionuse const)。

如果接口名称的第一个字符是大写I,第二个字母也是大写,则将删除前面的I。如果接口名称中包含“Interface”,则将其删除。在所有情况下,将向特质名称添加一个大写T。