[英]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.