为什么 E_WARNING 表现得像 E_ERROR?

Mir*_*ate 3 php error-handling phpseclib

我正在运行一个脚本,该脚本需要一个未正确包含在我的脚本中的文件。

PHP Fatal error: require_once(): Failed opening required 'Math/BigInteger.php' (include_path='.:/usr/share/php:/usr/share/pear') in /myDir/Net/SSH2.php on line 746

我有一个error_handler设置,它记录了我遇到的每个错误:

function script_error_handler($errno, $errstr, $errfile, $errline){
    echo "IN ERROR HANDLER\n";

    $GLOBALS['errors'][] = array(
        'errno'     => $errno,
        'errstr'    => $errstr,
        'errfile'   => $errfile,
        'errline'   => $errline
    );

    return true;
}
Run Code Online (Sandbox Code Playgroud)

我也有一个shutdown_function它稍后会通过错误来确定成功或失败(除其他外)。该函数的一部分打印我记录的错误。

function shutdown_handler($io) {
    print_r($GLOBALS['errors']);
    echo "\n";
    //irrelevant stuff ommitted
}
Run Code Online (Sandbox Code Playgroud)

奇怪的是,它的输出如下:

Array
(
    [0] => Array
        (
            [errno] => 2
            [errstr] => require_once(Math/BigInteger.php): failed to open stream: No such file or directory
            [errfile] => /myDir/Net/SSH2.php
            [errline] => 746
        )

)
Run Code Online (Sandbox Code Playgroud)

根据 PHP 的预定义常量2E_WARNING.

2 | E_WARNING (integer) | Run-time warnings (non-fatal errors). Execution of the script is not halted.

这似乎与Fatal Error我之前得到的输出明显冲突。为什么我E_ERROR在这种情况下没有得到?这里发生了什么?

CBr*_*roe 5

require/require_once生成警告致命错误。

如果没有你自己的错误处理,你应该得到这样的结果:

警告:require_once(foo) [function.require-once]:无法打开流:[…] 中没有这样的文件或目录

致命错误:require_once() [function.require]:打开所需的 'foo' (include_path='.') [...]

查看errstr您的输出,您会看到“无法打开流:没有这样的文件或目录”部分 - 所以WARNING的文本。

set_error_handler描述告诉你,

 “以下错误类型不能用用户定义的函数处理:E_ERROR, […]”

因此,正如预期的那样捕获了警告 - 而根据手册所说的,致命错误不是。