gpt4 book ai didi

php - 类方法调用前 Hook

转载 作者:行者123 更新时间:2023-12-02 15:36:23 25 4
gpt4 key购买 nike

在 PHP 5.X 中是否有可能在类中有一个方法,只要调用类方法,就会在被调用函数之前执行?我需要这个,因为我想对被调用函数中使用的参数进行一些动态验证。

class MyClass {

protected function preHook(){ echo "You are about to call a method."; }

public function methodA() { echo "You called methodA."; }

}

$obj = new MyClass();
$obj->methodA();
// Output: "You called methodA."
// Desired output: "You are about to call a method.You called methodA"

还请记住以下几点:“methodA”需要公开,因为代码中使用了反射来检测该方法。

最佳答案

如评论中所述,这是不可能的,因为只有在未定义给定名称的方法时才会调用 __call 魔术方法:

http://php.net/manual/en/language.oop5.magic.php

但是,也许以下 hackish 解决方案之一可以解决您的问题。

解决方案 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.phprunkit 是实验性的,所以这是相当硬核的。

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();

关于php - 类方法调用前 Hook ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16751703/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com