pajarotin/compose

Compose - PHP 中用于创建类/特质的工具,以“弗兰肯斯坦”的方式

v0.1.1 2023-09-30 13:15 UTC

This package is not auto-updated.

Last update: 2024-09-29 16:06:50 UTC


README

特性

  • 将组成的类标记为抽象
  • 将组成的类标记为最终
  • 设置组成的类/特质的命名空间
  • 设置组成的类的基本类
  • 向组成的类添加/删除接口
  • 向组成的类/特质添加/删除特性
  • 向组成的类添加/删除常量
  • 向组成的类/特质添加/删除属性
  • 向组成的类/特质添加/删除方法
  • 向组成的类/特质添加捐赠类的属性和方法
  • 向组成的类/特质添加捐赠特性的属性和方法
  • 向组成的类添加捐赠类的接口、特性、常量、属性和方法
  • 向组成的类添加捐赠类的常量
  • 延迟组成的类/特质的编译(组成代码的评估),与 PHP 自动加载系统链接
  • 延迟组成的类/特质的构建(组成类的配置),与 PHP 自动加载系统链接
  • 在编译前更新常量
  • 在编译前更新属性
  • 在编译前更新方法
  • ¡ 完全实验性代码 !

"优先使用组合而非继承"

此工具允许通过代码以代码块的形式组合类或特质,这些代码块来自先前的类或特质

  • 可以添加或从先前的类中复制常量(仅限于类)
  • 可以添加或从先前的类或特质中复制属性
  • 可以添加或从先前的类或特质中复制方法
  • 可以添加或从先前的类中复制特性
  • 可以添加或从先前的类中复制接口(仅限于类)
  • 在编译前可以删除任何部分
  • 在编译前也可以更新常量和属性

这些功能可以用于自动更改第三方源代码,而不必直接编辑它。

许可证

此软件在 [MIT] 许可证下分发。请阅读 LICENSE 了解软件可用性和分发信息。

示例

<?php
namespace Pajarotin\Test\Compose;
use Pajarotin\Compose\Compose as Compose;
require_once(dirname(__FILE__) . '/../../src/Compose.php');

// Suppose DonorSampleClass is a third party sourcecode, we shouldn't change
// but we need the hexadecimal value returned by getData
// We can override getData in derived class, but we cannot inherit property: $data and method: hash()
class DonorSampleClass {
    private $data;
    private function hash()  {
        return bin2hex($this->data);
    }
    public function getData() {
        return $this->data;
    }
    public function setData($value) {
        $this->data = $value;
    }
}

// We can define the desired behaviour in a dummy "Delta" class:
class DeltaCompose {
    public function getData() {
        return $this->hash();
    }
}

// Instead of changing the visibility in DonorSampleClass and inheriting, we compose:
$compose = new Compose('DesiredFinalClass', 'Pajarotin\\Test\\Compose');
$compose->fuseClass('DonorSampleClass', 'Pajarotin\\Test\\Compose');
$compose->fuseClass('DeltaCompose', 'Pajarotin\\Test\\Compose');
$compose->deferredCompilation();

$desired = new DesiredFinalClass();
$desired->setData('Bad Wolf');
$val = $desired->getData();

echo($val);

更新日志

查看 changelog

问题

  • 实验性代码,不建议用于生产
  • 组合完全“文本化”,将源代码行块复制以生成组合代码
  • 建议使用相同的捐赠类命名空间以获得更好的源代码兼容性
  • 如果复制代码使用 FILEDIR 或使用其捐赠类的名称,则可能会破坏
  • 函数源代码的提取不是很明智。如果闭包作为 addMethod 的参数内联,则添加闭包作为方法会失败。必须按照所示定义
// VALID
$closure = function($value) {
    $this->data = $value;
};
$compose->addMethod('setData', $closure, Compose::PRIVATE, Compose::INSTANCE, Compose::OVERRIDABLE, false);

// INVALID
$compose->addMethod('setData', function($value) { $this->data = $value; }, Compose::PRIVATE, Compose::STATIC, Compose::OVERRIDABLE, false);