正如评论中提到的,这是不可能的,因为只有在未定义具有给定名称的方法时才会调用 __call 魔术方法:
http://php.net/manual/en/language.oop5.magic.php
然而,也许以下丑陋的、骇人听闻的解决方案之一会让您满意。
解决方案 1
将需要更改所有方法名称:
class MyClass {
public function __call($name, $arguments){
echo "You are about to call $name method.";
return call_user_func_array(array($this, '_real_' . $name), $arguments);
}
private function _real_methodA() { echo "You called methodA."; }
}
$obj = new MyClass();
$obj->methodA();
解决方案 2
这将需要一个“包装”类:
class MyClass {
public function methodA() { echo "You called methodA."; }
}
class MyClassWrapper {
public function __construct(){
$this->myClass = new MyClass();
}
public function __call($name, $arguments){
echo "You are about to call $name method.";
return call_user_func_array(array($this->myClass, $name), $arguments);
}
}
$obj = new MyClassWrapper();
$obj->methodA();
解决方案 3
第三种方法是应用装饰器模式并创建一个包装器类。
class Decorator
{
protected $_instance;
public function __construct($instance)
{
$this->_instance = $instance;
}
public function __call($method, $args)
{
print 'do your stuff here';
return call_user_func_array(array($this->_instance, $method), $args);
}
}
$obj = new Decorator(new MyClass);
$obj->methodA();
解决方案 4
混合解决方案 1 并使用反射和“runkit_method_rename”重命名所有方法
http://docs.php.net/manual/en/function.runkit-method-rename.php
runkit 是实验性的,所以这是相当硬核的。
class MyClass {
public function __call($name, $arguments){
echo "You are about to call $name method.";
return call_user_func_array(array($this, '_real_' . $name), $arguments);
}
private function methodA() { echo "You called methodA."; }
}
$reflection = new ReflectionClass('MyClass');
$methods = $reflection->getMethods();
foreach ($methods as $method) {
runkit_method_rename('MyClass', $method->name , '_real_' . $method->name);
}
$obj = new MyClass();
$obj->methodA();