skrtdev/prototypes

一个简单的库,允许动态地向类添加方法

v1.1 2021-06-28 10:30 UTC

This package is auto-updated.

Last update: 2024-09-28 17:49:25 UTC


README

动态添加 PHP 类的方法

Scrutinizer Code Quality Build Status Codacy Badge php version
使用此库,您可以动态地向类添加方法,如下例所示

use skrtdev\Prototypes\Prototypeable;

class MyClass{
    use Prototypeable;
}

MyClass::addMethod('wow', function () {
    return "What a nice way to use PHP";
});

$instance = new MyClass();

echo $instance->wow();

输出为 What a nice way to use PHP

主要特性

  • 闭包绑定到原始对象,因此您可以在闭包中像编写类的方法一样访问 $this
  • 也支持 静态 方法,您可以访问 selfstatic
  • 尝试调用不存在的方法时,将抛出原生的 \Error
  • 如果类方法已存在、是原型、类不存在或不是可原型的(当使用 skrtdev\Prototypes\Prototypes::addMethod() 时),将抛出 skrtdev\Prototypes\Exception
  • 可以使用任何类型的 callable,而不仅仅是 Closure
  • 在原型方法中使用 命名参数

检查类是否可原型化

在尝试向类添加方法之前,您可能需要知道该类是否是 Prototypeable

您可以使用 isPrototypeable 方法

use skrtdev\Prototypes\Prototypes;

var_dump(Prototypes::isPrototypeable($instance::class)); // you must pass the class name as string (use get_class() in php7.x)
var_dump(Prototypes::isPrototypeable(MyClass::class));

有趣的事实

本身 Prototypes 类也是 Prototypeable,真奇怪。

已知问题

  • 此库没有 继承:您无法在子类中使用为类定义的原型方法。(这很快就会添加)
  • 您无法覆盖已经原型的方法,但很快就会添加。
  • 任何类型的 Error/Exception 在堆栈跟踪中看起来有点奇怪,并且方法名称被隐藏。也许有解决方案;如果您找到它,请随时提出 Issue/Pull Request

未来范围

  • 使用 class_parent() 实现某种类型的 继承。这可能会减慢在具有长继承层次结构的类中调用原型的速度。
  • 也许可以添加将方法添加到类中而不将其添加到其子类中的功能。(这有意义吗?)
  • 允许将普通/匿名类的所有方法添加到可原型的类中(使用 Reflection?)。
  • 添加定义已经作为原型定义的方法的功能,并覆盖它们。
  • 添加定义所有可原型化类的原型的功能。(您能看到任何用例吗?)