[英]PHP: Callback on Entry/Exit of Class Methods?
有没有一种方法可以在方法参数,条目和出口上设置回调(或自动记录),而无需在每个方法中进行显式调用? 我基本上想将此信息记录到我的logger类(静态)中,而不必为每个方法手动进行处理。
现在,我必须在每种方法中调用Logger :: logEntry()和Logger :: logExit()来完成此操作。 我希望不必这样做:
class TestClass {
public function tester($arg) {
Logger::logEntry();
Logger::info('Parameter $arg => ' . $arg);
// Do some stuff...
Logger::logExit();
}
}
使用包装器类。 此方法具有以下优点:
。
class LogWatch {
function __construct($class) {
$this->obj = $class;
}
function __call($method, $args) {
if (in_array($method, get_class_methods($this->obj) ) ) {
Logger::logEntry();
Logger::info('Parameter '.implode(', ', $args) );
call_user_func_array(array($this->obj, $method), $args);
Logger::logExit();
} else {
throw new BadMethodCallException();
}
}
}
$test = new LogWatch(new TestClass() );
$test->tester();
// you can use instances of `LogWatch()` just like your watched class
// including passing appropriate params:
$test->tester($param1, $param2);
如果为了调试而进行函数记录,则可能需要研究Xdebug扩展。 没有在运行时拦截函数调用的好方法,任何自动拦截都会增加巨大的运行时开销。
使用XDebug,您可以根据需要将其打开,以及获取许多其他内容
(因此,XDebug与PHPUnit一起用于进行单元测试和覆盖率分析。)
__call看起来可能是一个有趣的解决方案,但是这样做有3个问题,即
执行开销很大。 您正在执行__call-> call_user_func_array,这实际上不会在每个执行中添加一个,而是两个函数调用。
回溯变得难以理解:您试图调用的实际函数在__call和call_user_func_array的海洋中迷路了,从而使回溯变得异常困难,特别是如果回溯中包含了他们的争论列表。
愚蠢的隐藏函数:您将返回PHP4样式的“隐藏”函数,在函数前面加上_来阻止用户直接调用或查看它,因为如果函数名碰巧被命名为__call,不会触发,因此您已经有了一个充满了真正可怕的函数名称的整个类,开发人员将很想在任何地方直接调用它们。 (并且,如果您以后想摆脱__call,则必须重命名所有这些函数,以免破坏代码!)
因此,如果你正在使用的PHP代码来实现,这将导致epically可怕的代码,该代码库中的任何未来的用户将不会想工作。 您最好获得可以在需要时透明添加的东西(例如Xdebug),并节省大量污染您的代码。
您可以使用魔术函数__call
。 没有函数匹配该名称时将调用该函数。 重命名您的方法,使其带有前缀(例如,下划线),并可以选择将其设置为私有/受保护。
class TestClass {
public function __call($function, $args) {
Logger::logEntry();
Logger::info('Parameters: ' . implode(", ", $args);
$localFunc = "_" . $function;
$return = $this->$localFunc($args);
Logger::logExit();
return $return;
}
private function _tester() {
// do stuff...
return "tester called";
}
}
$t = new TestClass();
echo $t->tester();
// "tester called"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.