PHP运行时类修改(PHP runtime class modification)

2019-08-21 12:06发布

所以,我希望能够在运行时添加/删除类的方法。 之前你告诉我这是在接力可怕的初步实践,它可能是,但我真的不关心。 我希望能够做到这一点的原因是因为我想要的应用程序是非常模块化的,所以一些插件可以扩展一些基本的类和方法添加到它而不杀死的主要应用。

例如,说我有下面的类:

class User {
    protected $Id;
    protected $Name;
    protected $Password;
    protected $PostsPerPage;
 }

并说,有些插件添加的可能性为用户更改其可见性设置,增加了$ Visible属性的类。 类将成为:

class User {
    protected $Id;
    protected $Name;
    protected $Password;
    protected $PostsPerPage;
    protected $Visible;
 }

这可以通过__get和__set来实现,但最常见的实现是获取和设置运行时生成的属性,它会是一个麻烦,以电码伪getter和setter每个添加的属性,以及使用__set是无糖没有在我看来。

其他的想法我是单独存储用户设置,在像$ UserVisiblitySettings [用户ID]另一个数组,但这会使事情并不像面向对象,因为我想他们是。

接下来的想法是使一个辅助类,是这样的:

class UserHelper {
    public function SetVisiblity($user_object,value);
}

然后,我可以用__get和__set实行“朋友”的方法/类,但听起来太hackish的。 如果我一直这样下去还不如干脆超载__call,__get和__set。 此外,我不敢肯定这是很好的OOP初步实践,并且它会显得难看了。

最后我提出的想法是有一定的函数,在运行时使用的eval()(这是唯一有效的使用eval我能想出太)动态地创建类。 基本上,从文件中获取类的定义,做一些简单的支架找到找到类的开闭括号,然后邮寄到EVAL。

使用runkit是毫无疑问的,因为它已经过时,我宁可不强迫用户安装一些扩展。

当我仰望我的想法,最简单的一个,少CPU密集型似乎是超载_call并添加在类中注册方法的一种方式。

请未“不这样做”任何想法表示赞赏。

Answer 1:

RunKit扩展可以做到这一点( runkit_method_add()等)

但是它是一个实验性扩展,你就已经瞄准你的脚......

你有其他的选择:

  • 模仿新的领域,并与方法__get()__call()
  • 使用子类和工厂模式( class Plugin extends BaseImplementation并有工厂实例化Plugin ,而不是BaseImplementation )。 Zend的插件加载做这样的事情。
    这是一个与至少开销的解决方案,而且还仅限于扩展一个类中的一个插件。
  • 添加挂钩和使用授权(策略模式)( $this->plugin->onFoo() 有库此 。


Answer 2:

PHP不允许这样。 这可能是在其他方面的动态语言,但类系统是故意限制性的。 您可以安装runkit扩展,从而改变了语言,以便在运行时用类嘲讽有关(但你没有使用纯PHP了),或者你可以使用魔法的方法来模拟它。



Answer 3:

您可以覆盖类的,但我不知道你是否能在同一个请求重新加载它。 一些行为的改变可以与中介设计模式(symfony的事件调度程序)来实现,但是需要提前知道的扩展点,和火灾事件/邮件,并根据未来的延伸类捕获..

如果你能等待下一个请求,以及清除高速缓存,如果你拥有它。 我做了一个工具,它可以帮助你。 SourceEditor

这里有更多的答案类似的问题太多,在这里我把代码示例。 如何生成或在运行时修改PHP类?



文章来源: PHP runtime class modification