如何在PHP中向现有类添加方法?
我使用WordPress作为CMS,我想扩展它的一个类,而不必从另一个类继承;i、 e.我只想向该类“添加”更多方法:如何在PHP中向现有类添加方法?,php,class,extend,inheritance,Php,Class,Extend,Inheritance,我使用WordPress作为CMS,我想扩展它的一个类,而不必从另一个类继承;i、 e.我只想向该类“添加”更多方法: class A { function do_a() { echo 'a'; } } 然后: (将后者插入类的某种方式) 以及: 这在顽强的PHP中也是可能的吗? 你可以使用它,但是你应该真正地考虑正则继承。 请参阅。如果所讨论的类实现了调用魔法,那么它是可能的,而且非常简单。如果您想知道它是如何工作的,我建议您阅读。不,您不能在PHP运行时动态
class A {
function do_a() {
echo 'a';
}
}
然后:
(将后者插入类的某种方式)
以及:
这在顽强的PHP中也是可能的吗?
你可以使用它,但是你应该真正地考虑正则继承。请参阅。如果所讨论的类实现了调用魔法,那么它是可能的,而且非常简单。如果您想知道它是如何工作的,我建议您阅读。不,您不能在PHP运行时动态更改类 您可以通过使用常规继承扩展类来实现这一点:
class Fancy extends NotSoFancy
{
public function whatMakesItFancy() //can also be private/protected of course
{
//
}
}
或者您可以编辑Wordpress源文件
我更喜欢继承的方式。从长远来看,它更容易处理。如果您只需要访问类的公共API,可以使用: 然后包装SomeClass的实例:
$decorator = new SomeClassDecorator(new SomeClass);
$decorator->foo = 'bar'; // sets $foo in SomeClass instance
echo $decorator->foo; // returns 'bar'
echo $decorator->someMethod(); // forwards call to SomeClass instance
echo $decorator->myMethod(); // calls my custom methods in Decorator
如果需要访问受保护的API,则必须使用继承。如果需要访问
private
API,则必须修改类文件。虽然继承方法很好,但修改类文件可能会在更新时给您带来麻烦(您将丢失任何已制作的修补程序)。但两者都比使用runkit更可行。这是2014年应对范围的更新方式
public function __call($method, $arguments) {
return call_user_func_array(Closure::bind($this->$method, $this, get_called_class()), $arguments);
}
例如:
类stdObject{
公共函数调用($method,$arguments){
返回call_user_func_数组(Closure::bind($this->$method,$this,get_called_class()),$arguments);
}
}
$obj=新stdObject();
$obj->test=函数(){
echo“.print\u r($this,true)。”;
};
$obj->test();
编辑类源代码是一种选择吗?标题有误导性;“扩展”指的是继承。我把它改了,以便更好地反映你的问题。@谢谢。我觉得这有点模棱两可。。。。而runkit只不过是一个玩具。@johannes它有时在调试时很有用。但这就是我提出建议的原因,然而,这并不妨碍我回答这个问题。注意手册页面上的红色大“实验性”警告?不推荐用于任何生产用途…@Techpriester您的观点是什么?OP应该考虑使用另一种策略吗?我明白了,这个建议已经包含在回复中了。然而,这是一个有效的解决办法。尽管有人提出建议,我还是试图回答这个问题。此外,你假设得太多了。也许OP没有把它用于制作(他没有说他是)。也许他正以runkit为起点,编写自己的稳定扩展来实现同样的功能。无论什么我无意预测所有可能的情况;我试着将问题局限于实际问题,并将事后的猜测作为一种附带的游戏。是的,但我只是想明确指出,您不应该在其上构建一个关键的应用程序,该应用程序可以在ProductionProblem中运行,但它添加了大量讨厌的代码,以后可能很难维护。尤其是“$func=$foo->baz;$func();”上可能写满了失败的信息:我知道它很难维护,调试起来会很困难,我当然不建议使用它,但这是可能的:p.Great!。这不仅适用于向类添加新方法,还适用于在“extends”不是选项时覆盖它们。嗯……这实际上不会向原始对象添加方法,例如(与任何类型的继承或phpextends
),但这是一个基本上起作用的设计变通方法。这对于任何类名都非常有效。在$obj->test中,您还可以执行$this->someClassMethod()和$this->privateVarName。您还可以在成员函数中创建函数,这些函数可以访问类方法和变量。
class SomeClassDecorator
{
protected $_instance;
public function myMethod() {
return strtoupper( $this->_instance->someMethod() );
}
public function __construct(SomeClass $instance) {
$this->_instance = $instance;
}
public function __call($method, $args) {
return call_user_func_array(array($this->_instance, $method), $args);
}
public function __get($key) {
return $this->_instance->$key;
}
public function __set($key, $val) {
return $this->_instance->$key = $val;
}
// can implement additional (magic) methods here ...
}
$decorator = new SomeClassDecorator(new SomeClass);
$decorator->foo = 'bar'; // sets $foo in SomeClass instance
echo $decorator->foo; // returns 'bar'
echo $decorator->someMethod(); // forwards call to SomeClass instance
echo $decorator->myMethod(); // calls my custom methods in Decorator
public function __call($method, $arguments) {
return call_user_func_array(Closure::bind($this->$method, $this, get_called_class()), $arguments);
}
class stdObject {
public function __call($method, $arguments) {
return call_user_func_array(Closure::bind($this->$method, $this, get_called_class()), $arguments);
}
}
$obj = new stdObject();
$obj->test = function() {
echo "<pre>" . print_r($this, true) . "</pre>";
};
$obj->test();