如果錯誤處理程式(參見 set_error_handler)成功處理了錯誤,則該錯誤不會被此函數回報。
(PHP 5 >= 5.2.0, PHP 7, PHP 8)
error_get_last — 取得最後發生的錯誤
此函式沒有參數。
傳回一個關聯式陣列,描述最後一個錯誤,鍵值包含 "type"、"message"、"file" 和 "line"。如果錯誤是由 PHP 內部函式引起的,則 "message" 以其名稱開頭。如果尚未發生錯誤,則傳回 null
。
範例 #1 error_get_last() 範例
<?php
echo $a;
print_r(error_get_last());
?>
上述範例將輸出類似以下的內容
Array ( [type] => 8 [message] => Undefined variable: a [file] => C:\WWW\index.php [line] => 2 )
[編者註:自 PHP 7.0.0 起,可以使用 error_clear_last() 來清除最近的錯誤。]
要清除 error_get_last(),或將其設定為明確的狀態,您應該使用以下程式碼。即使設定了自訂錯誤處理程式,它也能正常運作。
<?php
// var_dump 或其他任何東西,因為由於 0 的關係,這永遠不會被呼叫
set_error_handler('var_dump', 0);
@$undef_var;
restore_error_handler();
// error_get_last() 現在處於已知狀態:
// 未定義的變數:undef_var
... // 執行某些操作
$e = error_get_last();
...
?>
即使錯誤因為您使用了 @ 字元、因為 php.ini 檔案中的「error_reporting」指令或因為您使用了 error_reporting() 函數而被隱藏,error_get_last() 函數仍會返回錯誤資訊。
範例
<?php
error_reporting(E_ALL ^ E_NOTICE);
$y = $x;
$err = error_get_last();
var_export($err);
?>
將顯示:array ( 'type' => 8, 'message' => '未定義的變數:x', 'file' => 'test.php', 'line' => 4, )
<?php
$y = @$x;
$err = error_get_last();
var_export($err);
?>
將顯示:array ( 'type' => 8, 'message' => '未定義的變數:x', 'file' => 'test.php', 'line' => 4, )
即使錯誤是致命錯誤,error_get_last() 函數也會返回最近的錯誤。
範例用法
<?php
register_shutdown_function('handleFatalPhpError');
function handleFatalPhpError() {
$last_error = error_get_last();
if ($last_error['type'] === E_ERROR) {
echo "可以在這裡為致命錯誤進行客製化輸出和/或記錄...";
}
}
?>
要注意的是,如果其他關閉函式拋出錯誤,註冊一個關閉函式來捕捉錯誤將無法運作。
<?php
register_shutdown_function('cleanupObjects');
register_shutdown_function('handleFatalPhpError');
function cleanupObjects() {
trigger_error('一個不重要的問題', E_USER_WARNING);
}
function handleFatalPhpError() {
$last_error = error_get_last();
if ($last_error['type'] === E_ERROR || $last_error['type'] === E_USER_ERROR) {
echo "可以在這裡為致命錯誤進行客製化輸出和/或記錄...";
}
}
trigger_error('嚴重的問題', E_USER_ERROR);
?>
在上面的程式碼中,因為 cleanupObjects() 會先被呼叫,$last_error 將會包含警告。
要在 php <5.2 中以一種不太理想的方式模擬這個函式,您可以使用類似以下的程式碼。
<?php
if (!function_exists('error_get_last')) {
set_error_handler(
create_function(
'$errno,$errstr,$errfile,$errline,$errcontext',
'
要知道在兩個陳述式之間是否發生了什麼事,當然可以使用一個帶有 user_error() 的特殊字串(代替 mail at mbaierl dot com 提到的內建特殊重置):<?php
@user_error($error_get_last_mark='error_get_last 標記');
$not_set;
$error_get_last=error_get_last();
$something_happened=($error_get_last['message']!=$error_get_last_mark); ?>
如果您的 <?php set_error_handler(function) ?> 函式回傳 true,那麼您就必須自行實作 error_get_last 的功能。(dmgx dot michael at gmail dot com 簡短提及)。
致手動審核者:關於 php.net/manual/add-note.php:由於我猜想上述技術上屬於「參考其他註釋」的範疇,我覺得有必要為自己辯護一下,我認為它在可用性方面可能會有幫助,尤其是在其他人說它失效的地方。還有,我沒有其他管道可以聯繫到閱讀 PHP 手冊註釋的讀者。
此外,您能否提供一些您認為可以接受的註釋範例?感謝您的審核。
如同 $php_errormsg,如果使用者自訂的錯誤處理器回傳非 FALSE 值,則此函式的回傳值可能不會更新。在 PHP 5.2.6 上測試。
<?php
var_dump(PHP_VERSION);
// 輸出:string(5) "5.2.6"
@trigger_error("foo");
$e=error_get_last();
var_dump($e['message']);
// 輸出:string(3) "foo"
set_error_handler(create_function('$a,$b',''));
@trigger_error("bar");
$e=error_get_last();
var_dump($e['message']);
// 輸出:string(3) "foo"
set_error_handler(create_function('$a,$b','return false;'));
@trigger_error("baz");
$e=error_get_last();
var_dump($e['message']);
// 輸出:string(3) "baz"
?>
它無法被完全重置,但您可以將其「清除」到足以應付所有實際用途。
<?php
@trigger_error("");
// 執行一些操作...
$e=error_get_last();
if($e['message']!==''){
// 發生錯誤
}
?>
請注意,error_get_last() 只會回傳未被攔截的錯誤。
被攔截的錯誤永遠不會傳遞到 error_get_last(),例如:
- 使用 set_error_handler() 註冊的 $error_levels,當 $callback 未回傳 false 時,
- 所有例外,包括 set_error_handler() 不支援的錯誤(例如:E_ERROR/致命錯誤、E_PARSE 等),這些實際上都是例外,
當 set_exception_handler($callback) 已註冊時,
- try/catch 區塊攔截的例外。
這是一個用於郵件函式的簡單除錯腳本…
<?php
// 由 Manomite 建立,用於除錯
class Error{
function __construct(){
error_reporting ( E_ALL ^ E_NOTICE );
$err = error_get_last ();
if($err){
$res = "您的應用程式發生錯誤,先生。\n 詳細資訊包含 " .$err.""
mail("admin@manomite.net","發生錯誤",$res,$from);
}
}
}
?>
如果您需要在 PHP 5.2 之前檢查錯誤是否為致命錯誤(在我的情況下,在輸出緩衝處理程式中),您可以使用以下技巧
<?php
# 檢查是否有 PHP 致命錯誤。
# 使用 error_get_last 是「正確的」方法,但它需要 PHP 5.2+。備份是一個技巧。
if (function_exists('error_get_last')) {
$lastPHPError = error_get_last();
$phpFatalError = isset($lastPHPError) && $lastPHPError['type'] === E_ERROR;
} else {
$phpFatalError = strstr($output, '<b>致命錯誤</b>:') && ! strstr($output, '</html>');
}
?>
當然,這取決於語言,因此在廣泛發佈的程式碼中並不好,但在某些情況下可能會有幫助(或者至少可以作為有效方法的基礎)。
雖然 mail at mbaierl dot com 指出此函式並非最適合報告最近執行步驟的可能錯誤狀況,但在某些情況下,了解最後一個錯誤特別有用,無論它何時發生。
舉例來說,假設您有一些程式碼可以擷取動態頁面的輸出,並將其快取以便更快地傳遞給後續的訪客。最後的健全性檢查是查看腳本執行期間是否發生錯誤。如果發生錯誤,我們可能不想快取該頁面。