僅限 PHP5(僅使用 php5.0 測試過)。
如果您因為某些原因偏好例外而不是錯誤,並且您的自訂錯誤處理程式 (set_error_handler) 將錯誤包裝成例外,那麼您必須小心您的腳本。
因為如果您不是只呼叫例外處理程式,而是拋出例外,並且有一個自訂例外處理程式 (set_exception_handler)。而且在該例外處理程式內觸發了錯誤,您將會收到一個奇怪的錯誤
「致命錯誤:在第 0 行的未知位置拋出無堆疊框架的例外」
這個錯誤訊息並不是特別有用,對吧? :)
下面的例子將會導致這個錯誤。
<?php
類別 PHPErrorException 延伸 Exception
{
私有 $context = null;
公開 函數 __construct
($code, $message, $file, $line, $context = null)
{
parent::__construct($message, $code);
$this->file = $file;
$this->line = $line;
$this->context = $context;
}
};
函數 error_handler($code, $message, $file, $line) {
拋出 新 PHPErrorException($code, $message, $file, $line);
}
函數 exception_handler(Exception $e)
{
$errors = 陣列(
E_USER_ERROR => "使用者錯誤",
E_USER_WARNING => "使用者警告",
E_USER_NOTICE => "使用者注意",
);
顯示 $errors[$e->getCode()].': '.$e->getMessage().' 於 '.$e->getFile().
' 第 '.$e->getLine()." 行\n";
顯示 $e->getTraceAsString();
}
set_error_handler('error_handler');
set_exception_handler('exception_handler');
拋出 新 Exception('foo', 0);
?>
然而,這問題很容易修復,因為它只是粗心程式碼造成的。
例如,直接從 error_handler 呼叫 exception_handler 而不是拋出例外。這不僅解決了這個問題,而且速度更快。 雖然這會導致印出一個「普通的」未處理例外,如果只想顯示「設計好的」錯誤訊息,這並不是最終的解決方案。
那麼,該怎麼做呢?確保 exception_handler 中的程式碼不會造成任何錯誤!在這個例子中,一個簡單的 isset() 就可以解決它。
此致,C-A B.