【发布时间】:2010-12-08 06:54:03
【问题描述】:
所以我希望能够在运行时添加/删除类方法。在你告诉我这是糟糕的 oop 练习之前,它可能是,但我并不在乎。我希望能够做到这一点的原因是因为我希望应用程序非常模块化,因此某些插件可以扩展一些基类并向其添加方法而不会杀死主应用程序。
例如,假设我有以下课程:
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[userid],但这使得事情不像我希望的那样 OO。
下一个想法是创建一个辅助类,如下所示:
class UserHelper {
public function SetVisiblity($user_object,value);
}
然后,我可以使用 __get 和 __set 来实现“朋友”方法/类,但这听起来太老套了。如果我要那样做,还不如重载 __call、__get 和 __set。此外,我不太确定这是一种好的 OOP 做法,而且看起来也很丑。
我的最后一个想法是使用 eval() 在运行时动态创建类的函数(这也是我能想到的唯一有效的 eval 用法)。基本上,从文件中获取类定义,做一些简单的括号查找来找到类的开始和结束括号并将其发送到 eval。
使用runkit是没有问题的,因为它已经过时了,我不想强迫用户安装一些扩展。
当我查看我的想法时,最简单且 CPU 密集度较低的方法似乎是重载 _call 并添加一种在类中注册方法的方法。
请感谢任何不是“不要这样做”的想法。
【问题讨论】:
-
本质上,您正在寻找 ruby 的扩展/包含机制 (ruby-doc.org/core/classes/Object.html#M000335) 或(在某种程度上)C# 的扩展方法 (msdn.microsoft.com/en-us/library/bb383977.aspx) 的对应物?
-
和C#的扩展方法一模一样
标签: php oop reflection class dynamic