set_error_handler

(PHP 4 >= 4.0.1, PHP 5, PHP 7, PHP 8)

set_error_handler設(shè)置用戶(hù)自定義的錯(cuò)誤處理函數(shù)

說(shuō)明

set_error_handler(callable $error_handler, int $error_types = E_ALL | E_STRICT): mixed

設(shè)置用戶(hù)的函數(shù) (error_handler) 來(lái)處理腳本中出現(xiàn)的錯(cuò)誤。

本函數(shù)可以用你自己定義的方式來(lái)處理運(yùn)行中的錯(cuò)誤, 例如,在應(yīng)用程序中嚴(yán)重錯(cuò)誤發(fā)生時(shí),或者在特定條件下觸發(fā)了一個(gè)錯(cuò)誤(使用 trigger_error()),你需要對(duì)數(shù)據(jù)/文件做清理回收。

重要的是要記住 error_types 里指定的錯(cuò)誤類(lèi)型都會(huì)繞過(guò) PHP 標(biāo)準(zhǔn)錯(cuò)誤處理程序, 除非回調(diào)函數(shù)返回了 false。 error_reporting() 設(shè)置將不會(huì)起到作用而你的錯(cuò)誤處理函數(shù)繼續(xù)會(huì)被調(diào)用 —— 不過(guò)你仍然可以獲取 error_reporting 的當(dāng)前值,并做適當(dāng)處理。 需要特別注意的是帶 @ error-control operator 前綴的語(yǔ)句發(fā)生錯(cuò)誤時(shí),這個(gè)值會(huì)是 0。

同時(shí)注意,在需要時(shí)你有責(zé)任使用 die()。 如果錯(cuò)誤處理程序返回了,腳本將會(huì)繼續(xù)執(zhí)行發(fā)生錯(cuò)誤的后一行。

以下級(jí)別的錯(cuò)誤不能由用戶(hù)定義的函數(shù)來(lái)處理,獨(dú)立于發(fā)生錯(cuò)誤的地方: E_ERROR、 E_PARSEE_CORE_ERROR、 E_CORE_WARNING、 E_COMPILE_ERROR、 E_COMPILE_WARNING,和在 調(diào)用 set_error_handler() 函數(shù)所在文件中產(chǎn)生的大多數(shù) E_STRICT。

如果錯(cuò)誤發(fā)生在腳本執(zhí)行之前(比如文件上傳時(shí)),將不會(huì) 調(diào)用自定義的錯(cuò)誤處理程序因?yàn)樗形丛谀菚r(shí)注冊(cè)。

參數(shù)

error_handler

以下格式的回調(diào)(callback): 可以傳入 null 重置處理程序到默認(rèn)狀態(tài)。 除了可以傳入函數(shù)名,還可以傳入引用對(duì)象和對(duì)象方法名的數(shù)組。

handler(
    int $errno,
    string $errstr,
    string $errfile = ?,
    int $errline = ?,
    array $errcontext = ?
): bool
errno
第一個(gè)參數(shù) errno,包含了錯(cuò)誤的級(jí)別,是一個(gè) integer。
errstr
第二個(gè)參數(shù) errstr,包含了錯(cuò)誤的信息,是一個(gè) string。
errfile
第三個(gè)參數(shù)是可選的,errfile, 包含了發(fā)生錯(cuò)誤的文件名,是一個(gè) string。
errline
第四個(gè)參數(shù)是一個(gè)可選項(xiàng), errline, 包含了錯(cuò)誤發(fā)生的行號(hào),是一個(gè) integer。
errcontext
第五個(gè)可選參數(shù), errcontext, 是一個(gè)指向錯(cuò)誤發(fā)生時(shí)活動(dòng)符號(hào)表的 array。 也就是說(shuō),errcontext 會(huì)包含錯(cuò)誤觸發(fā)處作用域內(nèi)所有變量的數(shù)組。 用戶(hù)的錯(cuò)誤處理程序不應(yīng)該修改錯(cuò)誤上下文(context)。
警告

PHP 7.2.0 后此參數(shù)被棄用了。 極其不建議依賴(lài)它。

如果函數(shù)返回 false,標(biāo)準(zhǔn)錯(cuò)誤處理處理程序?qū)?huì)繼續(xù)調(diào)用。

error_types

就像error_reporting 的 ini 設(shè)置能夠控制錯(cuò)誤的顯示一樣, 此參數(shù)能夠用于屏蔽 error_handler 的觸發(fā)。 如果沒(méi)有該掩碼, 無(wú)論 error_reporting 是如何設(shè)置的, error_handler 都會(huì)在每個(gè)錯(cuò)誤發(fā)生時(shí)被調(diào)用。

返回值

如果之前有定義過(guò)錯(cuò)誤處理程序,則返回該程序名稱(chēng)的 string;如果是內(nèi)置的錯(cuò)誤處理程序,則返回 null。 如果你指定了一個(gè)無(wú)效的回調(diào)函數(shù),同樣會(huì)返回 null。 如果之前的錯(cuò)誤處理程序是一個(gè)類(lèi)的方法,此函數(shù)會(huì)返回一個(gè)帶類(lèi)和方法名的索引數(shù)組(indexed array)。

更新日志

版本 說(shuō)明
7.2.0 errcontext 被廢棄。 使用此參數(shù)時(shí)會(huì)導(dǎo)致 E_DEPRECATED 提醒。

范例

示例 #1 用 set_error_handler()trigger_error() 進(jìn)行錯(cuò)誤處理

以下示例展示了通過(guò)觸發(fā)錯(cuò)誤并以用戶(hù)自定義的程序來(lái)進(jìn)行內(nèi)部異常的處理。

<?php
// error handler function
function myErrorHandler($errno$errstr$errfile$errline)
{
    if (!(
error_reporting() & $errno)) {
        
// This error code is not included in error_reporting, so let it fall
        // through to the standard PHP error handler
        
return false;
    }

    
// $errstr may need to be escaped:
    
$errstr htmlspecialchars($errstr);

    switch (
$errno) {
    case 
E_USER_ERROR:
        echo 
"<b>My ERROR</b> [$errno$errstr<br />\n";
        echo 
"  Fatal error on line $errline in file $errfile";
        echo 
", PHP " PHP_VERSION " (" PHP_OS ")<br />\n";
        echo 
"Aborting...<br />\n";
        exit(
1);

    case 
E_USER_WARNING:
        echo 
"<b>My WARNING</b> [$errno$errstr<br />\n";
        break;

    case 
E_USER_NOTICE:
        echo 
"<b>My NOTICE</b> [$errno$errstr<br />\n";
        break;

    default:
        echo 
"Unknown error type: [$errno$errstr<br />\n";
        break;
    }

    
/* Don't execute PHP internal error handler */
    
return true;
}

// function to test the error handling
function scale_by_log($vect$scale)
{
    if (!
is_numeric($scale) || $scale <= 0) {
        
trigger_error("log(x) for x <= 0 is undefined, you used: scale = $scale"E_USER_ERROR);
    }

    if (!
is_array($vect)) {
        
trigger_error("Incorrect input vector, array of values expected"E_USER_WARNING);
        return 
null;
    }

    
$temp = array();
    foreach(
$vect as $pos => $value) {
        if (!
is_numeric($value)) {
            
trigger_error("Value at position $pos is not a number, using 0 (zero)"E_USER_NOTICE);
            
$value 0;
        }
        
$temp[$pos] = log($scale) * $value;
    }

    return 
$temp;
}

// set to the user defined error handler
$old_error_handler set_error_handler("myErrorHandler");

// trigger some errors, first define a mixed array with a non-numeric item
echo "vector a\n";
$a = array(23"foo"5.543.321.11);
print_r($a);

// now generate second array
echo "----\nvector b - a notice (b = log(PI) * a)\n";
/* Value at position $pos is not a number, using 0 (zero) */
$b scale_by_log($aM_PI);
print_r($b);

// this is trouble, we pass a string instead of an array
echo "----\nvector c - a warning\n";
/* Incorrect input vector, array of values expected */
$c scale_by_log("not array"2.3);
var_dump($c); // NULL

// this is a critical error, log of zero or negative number is undefined
echo "----\nvector d - fatal error\n";
/* log(x) for x <= 0 is undefined, you used: scale = $scale" */
$d scale_by_log($a, -2.5);
var_dump($d); // Never reached
?>

以上例程的輸出類(lèi)似于:

vector a
Array
(
    [0] => 2
    [1] => 3
    [2] => foo
    [3] => 5.5
    [4] => 43.3
    [5] => 21.11
)
----
vector b - a notice (b = log(PI) * a)
<b>My NOTICE</b> [1024] Value at position 2 is not a number, using 0 (zero)<br />
Array
(
    [0] => 2.2894597716988
    [1] => 3.4341896575482
    [2] => 0
    [3] => 6.2960143721717
    [4] => 49.566804057279
    [5] => 24.165247890281
)
----
vector c - a warning
<b>My WARNING</b> [512] Incorrect input vector, array of values expected<br />
NULL
----
vector d - fatal error
<b>My ERROR</b> [256] log(x) for x <= 0 is undefined, you used: scale = -2.5<br />
  Fatal error on line 35 in file trigger_error.php, PHP 5.2.1 (FreeBSD)<br />
Aborting...<br />

參見(jiàn)