Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP:类方法进入/退出时的回调?_Php_Logging_Methods_Callback_Stack Trace - Fatal编程技术网

PHP:类方法进入/退出时的回调?

PHP:类方法进入/退出时的回调?,php,logging,methods,callback,stack-trace,Php,Logging,Methods,Callback,Stack Trace,是否有一种方法可以设置回调或自动记录方法参数、条目和出口,而无需在每个方法中进行显式调用?我基本上希望将这些信息记录到我的logger类中,它是静态的,而不必为每个方法手动执行 现在我必须在每个方法中调用Logger::logEntry和Logger::logExit来完成这项任务。我希望不必这样做: class TestClass { public function tester($arg) { Logger::logEntry(); Logger::i

是否有一种方法可以设置回调或自动记录方法参数、条目和出口,而无需在每个方法中进行显式调用?我基本上希望将这些信息记录到我的logger类中,它是静态的,而不必为每个方法手动执行

现在我必须在每个方法中调用Logger::logEntry和Logger::logExit来完成这项任务。我希望不必这样做:

class TestClass {
    public function tester($arg) {
        Logger::logEntry();
        Logger::info('Parameter $arg => ' . $arg);

        // Do some stuff...

        Logger::logExit();
    }
}

你可以使用神奇的函数调用。当没有与该名称匹配的函数时调用它。将方法重命名为前缀,例如下划线,并可以选择将它们设置为private/protected

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"

你可以使用神奇的函数调用。当没有与该名称匹配的函数时调用它。将方法重命名为前缀,例如下划线,并可以选择将它们设置为private/protected

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"

如果您希望为了调试而进行函数记录,那么您可能需要查看Xdebug扩展。在运行时拦截函数调用没有好方法,任何自动拦截都会增加巨大的运行时开销

使用XDebug,您可以根据需要打开它,还可以获得许多其他东西

因此,XDebug与PHPUnit一起用于进行单元测试和覆盖率分析

电话的问题 __call可能看起来是一个有趣的问题解决方案,但它有三个问题,即

显著的执行开销。您的doing _call->call _user _func_数组,它实际上不会为每次执行添加一个函数调用,而是添加两个函数调用

回溯变得难以理解:您试图调用的实际函数在大量的_调用和call_user_func_数组中丢失,这使得回溯非常困难,尤其是当您的回溯包含其参数列表时

愚蠢的隐藏函数:你要回到PHP4风格的函数隐藏,在它们前面加上u,以阻止用户直接调用或看到它,因为如果函数名恰好被命名为它们不想要的名称,那么u调用将不会触发,所以你已经得到了一整类非常可怕的函数名,无论在什么地方,开发者都会直接打电话给他们。如果你以后想摆脱_调用,你必须重命名所有这些函数,以免破坏代码


因此,如果您使用php代码来实现这一点,将导致代码库的任何未来用户都不愿意使用的可怕代码。您最好得到像Xdebug这样的东西,在需要时可以透明地添加它,并大大节省代码

如果您想为了调试而进行函数日志记录,您可能需要查看Xdebug扩展。在运行时拦截函数调用没有好方法,任何自动拦截都会增加巨大的运行时开销

使用XDebug,您可以根据需要打开它,还可以获得许多其他东西

因此,XDebug与PHPUnit一起用于进行单元测试和覆盖率分析

电话的问题 __call可能看起来是一个有趣的问题解决方案,但它有三个问题,即

显著的执行开销。您的doing _call->call _user _func_数组,它实际上不会为每次执行添加一个函数调用,而是添加两个函数调用

回溯变得难以理解:您试图调用的实际函数在大量的_调用和call_user_func_数组中丢失,这使得回溯非常困难,尤其是当您的回溯包含其参数列表时

愚蠢的隐藏函数:你要回到PHP4风格的函数隐藏,在它们前面加上u,以阻止用户直接调用或看到它,因为如果函数名恰好被命名为它们不想要的名称,那么u调用将不会触发,所以你已经得到了一整类非常可怕的函数名,无论在什么地方,开发者都会直接打电话给他们。如果你以后想摆脱_调用,你必须重命名所有这些函数,以免破坏代码


因此,如果您使用php代码来实现这一点,将导致代码库的任何未来用户都不愿意使用的可怕代码。您最好得到像Xdebug这样的东西,在需要时可以透明地添加它,并大大节省代码

使用包装器类。此方法具有以下优点:

无需更改基础类结构/方法签名 更改日志记录?只需更新这个类 更新对象调用,而不是向要记录的每个类中插入代码


使用包装器类。此方法具有以下优点:

无需更改基础类结构/方法签名 更改日志记录?只需更新这个类 更新对象调用,而不是向要记录的每个类中插入代码

一定的
我同意,但是如果出于任何原因必须这样做,我更喜欢不将记录器绑定到它试图记录的类的方法。我绝对同意,但是,如果出于任何原因必须这样做,我更喜欢不将记录器绑定到它试图记录的类的方法。在用户函数前加前缀是非常糟糕的风格。它不会改变任何其他人的代码-你必须改变自己的代码。或者,只需将方法更改为private或protected。为用户的函数添加前缀是一种非常糟糕的风格。它不会更改任何其他人的代码-您必须更改自己的代码。或者,只需将方法更改为private或protected。