PHP捕获致命错误的时候没有显示异常?

查看:108
本文介绍了PHP捕获致命错误的时候没有显示异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

在PHP中自己想要试用自定义的异常处理函数捕获所有的错误处理,并且输出具有一定格式的错误信息,包括致命错误和非致命错误,在处理非致命错误上输出是没问题的,但是输出致命错误的时候,并没有输出,代码如下:

<?php
/**
 * 使用自定义的异常处理函数,捕获所有的错误处理,包括非致命的和致命的
 */

// 屏蔽所有的错误显示
error_reporting(0);

// 使用自定义的异常处理函数来替代PHP的错误处理
set_error_handler('customError');

// 当PHP终止的时候(执行完成或者是遇到致命错误中止的时候)会调用FetalError方法
register_shutdown_function('FetalError');

/**
 * 自定义的异常处理函数
 * @param $errno int
 * @param $errstr string
 * @param $errfile string
 * @param $errline int
 * @throws Exception
 */
function customError($errno, $errstr, $errfile, $errline)
{
    $res = PHP_EOL . " 错误代码: [${errno}] ${errstr}" . PHP_EOL;
    $res .= " 错误所在的代码行: {$errline}";
    $res .= " 文件: {$errfile}" . PHP_EOL;
    $res .= " PHP版本:" . PHP_VERSION . "(" . PHP_OS . ")" . PHP_EOL;
    // 自定义错误处理时,手动抛出异常
    throw new Exception($res);
    // echo $res;
}

/**
 * 捕获致命错误
 */
function FetalError()
{
    $err_info = error_get_last();
    if ($err_info) {
        customError($err_info['type'], $err_info['message'], $err_info['file'], $err_info['line']);
    }
}

function test()
{
    // Warning错误
//    $a = 5 / 0;
//    echo PHP_EOL;

    // 这里报致命错误Fatal error
    $a = new a();
    echo PHP_EOL;

    // 这里会报致命错误Fatal error
    echo fun();

    echo PHP_EOL;
    echo "after";
    echo PHP_EOL;
}

try {
    test();
    
    // 其他的业务逻辑,可能会抛出异常
} catch (Exception $e) {
    var_dump(11111);
    echo $e->getMessage();
}

运行之后什么都没有输出,而如果把customError方法的throw注释掉,换成echo $res,就没问题,请问为什么不能用throw?并且test方法里面的注释的那些非致命错误使用throw就可以正常输出的?为什么要用throw呢,这是因为try中除了test方法,可能还有其他的业务逻辑会抛出异常,所以我是打算把所有的异常和错误都在catch中进行捕获、错误输出以及错误处理,所以需要customError方法中进行throw抛出异常。

如果把error_reporting(0)注释掉,是可以显示的,如下:

λ php 1_25_allError.php

Fatal error: Uncaught Error: Class 'a' not found in C:\laragon\www\php_book\1_25_allError.php on line 67

Error: Class 'a' not found in C:\laragon\www\php_book\1_25_allError.php on line 67

Call Stack:
    0.0000     355368   1. {main}() C:\laragon\www\php_book\1_25_allError.php:0
    0.0000     355664   2. test() C:\laragon\www\php_book\1_25_allError.php:79


 错误代码: [1] Uncaught Error: Class 'a' not found in C:\laragon\www\php_book\1_25_allError.php:67
Stack trace:
#0 C:\laragon\www\php_book\1_25_allError.php(79): test()
#1 {main}
  thrown
 错误所在的代码行: 67 文件: C:\laragon\www\php_book\1_25_allError.php
 PHP版本:7.1.1(WINNT)

但是也会输出PHP自带的致命错误信息,我是想要屏蔽致命错误信息并且使用自定义异常处理函数即customError来输出致命错误信息的。

解决方案

error_reporting(0)意味着关闭错误输出,这里不能关闭,关闭就不报错了。

<?php
/**
 * 使用自定义的异常处理函数,捕获所有的错误处理,包括非致命的和致命的
 */

ini_set('display_errors', false);
// 屏蔽所有的错误显示
//error_reporting(0);

// 使用自定义的异常处理函数来替代PHP的错误处理
set_error_handler('customError');

set_exception_handler('handleException');

// 当PHP终止的时候(执行完成或者是遇到致命错误中止的时候)会调用FetalError方法
register_shutdown_function('FetalError');

/**
 * 自定义的异常处理函数
 * @param $errno int
 * @param $errstr string
 * @param $errfile string
 * @param $errline int
 * @throws Exception
 */
function customError($errno, $errstr, $errfile, $errline)
{
    $res = PHP_EOL . " 错误代码: [${errno}] ${errstr}" . PHP_EOL;
    $res .= " 错误所在的代码行: {$errline}";
    $res .= " 文件: {$errfile}" . PHP_EOL;
    $res .= " PHP版本:" . PHP_VERSION . "(" . PHP_OS . ")" . PHP_EOL;
    // 自定义错误处理时,手动抛出异常
    throw new Exception($res);
    // echo $res;
}

/**
 * 捕获致命错误
 */
function FetalError()
{
    $err_info = error_get_last();
    if ($err_info) {
        print_r($err_info);
    }
}

function test()
{
//    $a = ['o' => 2, 4, 6, 8];
//    // 由于这里没有加引号,所以这里会报Notice
//    echo $a[o];
//    echo PHP_EOL;
//
//    // 由于array_sum只能接收一个参数,所以这里会报Warning
//    $result = array_sum($a, 3);
//    echo PHP_EOL;
//
//    // 由于$i没有定义,所以这里会报Notice
//    if ($i > 5) {
//        echo '$i 没有初始化' , PHP_EOL;
//    }
//    echo PHP_EOL;
//
//    // Warning错误
//    $a = 5 / 0;
//    echo PHP_EOL;

    // 这里报致命错误Fatal error
    $a = new a();
    echo PHP_EOL;

    // 这里会报致命错误Fatal error
    echo fun();

    echo PHP_EOL;
    echo "after";
    echo PHP_EOL;
}

try {
    test();
} catch (Exception $e) {
    var_dump(11111);
    echo $e->getMessage();
}

function handleException($e)
{
    print_r($e);
}

register_shutdown_function 当PHP终止的时候执行,可以这样理解调用条件:

  1. 当页面被用户强制停止时
  2. 当程序代码运行超时时
  3. 当PHP代码执行完成时,代码执行存在异常和错误、警告

那你的代码可以参考我上面的,记得关闭display_errors。不然PHP自己会输出错误。

这篇关于PHP捕获致命错误的时候没有显示异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆