有人能告訴我,最常見的原因,看看在PHP這樣的錯誤:無法銷燬活動lambda函數
無法銷燬活動拉姆達功能...
我猜某處有代碼試圖銷燬包含對自身的引用的閉包,編譯器對此感到惱火。
我們得到這些比我想要的更經常,我想知道我們使用什麼樣的模式,這是造成它的可能的罪魁禍首。
我會附上一段代碼,但錯誤通常指向文件而不是可能提供提示的文件中的一行。
有人能告訴我,最常見的原因,看看在PHP這樣的錯誤:無法銷燬活動lambda函數
無法銷燬活動拉姆達功能...
我猜某處有代碼試圖銷燬包含對自身的引用的閉包,編譯器對此感到惱火。
我們得到這些比我想要的更經常,我想知道我們使用什麼樣的模式,這是造成它的可能的罪魁禍首。
我會附上一段代碼,但錯誤通常指向文件而不是可能提供提示的文件中的一行。
這樣會導致這樣的代碼一個致命的錯誤:
set_exception_handler(function ($e) {
echo "My exception handler";
restore_exception_handler();
throw new Exception("Throw this instead.");
});
throw new Exception("An exception");
或者這樣:
function destroy_handler() {
restore_exception_handler();
}
function update_handler() {
destroy_handler();
}
set_exception_handler(function ($e) {
echo "My exception handler";
update_handler();
throw new Exception("Throw this instead.");
});
throw new Exception("An exception");
當一個異常被拋出給set_exception_handler()
回調執行並且一旦調用restore_exception_handler()
,就會發生致命錯誤,因爲對該閉包的相同引用正在被de (或重新分配)在自己的範圍內(在Sameer K
發佈的鏈接中的hanskrentel at yahoo dot de
的示例中也是如此)。
從第二個例子可以看出,即使是嵌套的作用域,也會發生同樣的情況。這是因爲restore_exception_handler
會銷燬最後一個設置的異常處理程序,而不是它的副本(就像在重新分配變量或取消設置時,仍然計算將給變量賦予初始值的表達式)。
如果您說代碼中的錯誤指向了另一個文件,我建議您檢查lambda中的所有調用,在函數和/或其他文件中的方法執行「跳轉」,並檢查是否重新分配或破壞對lambda本身的引用。
的set_exception_handler
將返回前一個異常處理程序:
返回先前定義的異常處理程序,或者在錯誤NULL的名稱。如果沒有定義以前的處理程序,則返回NULL。 php.net: set_exception_handler
<?php
class MyException extends Exception {}
set_exception_handler(function(Exception $e){
echo "Old handler:".$e->getMessage();
});
$lastHandler = set_exception_handler(function(Exception $e) use (&$lastHandler) {
if ($e instanceof MyException) {
echo "New handler:".$e->getMessage();
return;
}
if (is_callable($lastHandler)) {
return call_user_func_array($lastHandler, [$e]);
}
throw $e;
});
觸發異常處理程序:
throw new MyException("Exception one", 1);
輸出:New handler:Exception one
throw new Exception("Exception two", 1);
輸出:Old handler:Exception two