register_shutdown_function无法捕获致命错误:(未捕获的错误未设置静态属性示例,对未定义函数prom()的调用)

时间:2019-01-17 21:08:58

标签: php error-handling

我有这个:

  1. 我有一个HTTACCESS文件,该文件带有指令以在文件之前添加配置文件并处理错误:(这是强制性的:根据文档,必须在任何其他php脚本之前附加此文件是为了获取错误而执行的,例如E_PARSE。)

    php_value auto_prepend_file "./server/conferror.php"
    
  2. conferror.php的内容:

    <?php
    declare(strict_types=1);
    ini_set('session.gc_maxlifetime', '0');
    ini_set('session.use_only_cookies', '1');
    ini_set('session.cookie_httponly', '1');
    ini_set('allow_url_fopen', '1');
    ini_set('allow_url_include', '1');
    ini_set('error_reporting', '1');
    ini_set('display_errors', '0');
    error_reporting(E_ALL);
    set_error_handler("ErrorHandler");
    register_shutdown_function("ShutdownHandler");
    function ErrorHandler($error_level, $error_message, $error_file, $error_line, $error_context) {
        $ErrorHandler = "<b>File:</b> " . $error_file . '<br>' .
            "<b>Line :</b> " . $error_line . '<br>' .
            "<b>Desc:</b> <br>" . $error_message . '<br>';
        echo $ErrorHandler;
        exit;
    }
    function ShutdownHandler() {
        $CheckError = error_get_last();
        if ($CheckError != null) {
            $ErrorHandler = "<b>File:</b> " . $CheckError['file'] . '<br>' .
                "<b>Line :</b> " . $CheckError['line'] . '<br>' .
                "<b>Desc:</b> <br>" . $CheckError['message'] . '<br>';
            echo $ErrorHandler;
            exit;
        }
    }
    ?>
    
  3. 在我的index.php中,我有这个要开始应用了:

    <?php
        require_once 'class.Main.php';
        $WebAPP = new CORE();
        $WebAPP->Main();
    ?>
    
  4. 在主文件中,我有一个测试,此代码可取消设置静态对象并测试Erros处理程序:

    <?php
    class CORE {
        public static $ObjClass;
        public function __construct() {
            self::$ObjClass['data']='data';
        }
        public function __destruct() {
            unset(CORE::$ObjClass);
        }
        public function Main() {
            #not Test on this.
        }
    }
    ?>
    

我有3个问题:

  1. 为什么事件处理程序无法捕获以下错误?
  

致命错误:未捕获错误:尝试取消设置静态属性CORE :: $ ObjClass在C:\ xampp \ htdocs \ dev \ t2 \ class.Main.php:8堆栈跟踪:#0 [内部函数]:CORE- > __ destruct()#1 {main}在第8行的C:\ xampp \ htdocs \ dev \ t2 \ class.Main.php中抛出

第二项测试

此代码:

<?php
class CORE {
    public function __construct() {
    }
    public function __destruct() {
        prom();
    }
    public function Main() {
        #not Test on this.
    }
}
?>

产生此错误:

  

致命错误:未捕获错误:调用C:\ xampp \ htdocs \ dev \ t2 \ class.Main.php:6中未定义的函数prom()堆栈跟踪:#0 [内部函数]:CORE-> __ destruct( )#1 {main}在第6行的C:\ xampp \ htdocs \ dev \ t2 \ class.Main.php中抛出

更新

经过大量测试,我发现错误处理程序可以很好地处理声明的函数中的错误;但这不适用于__construct__destruct函数。

2 个答案:

答案 0 :(得分:1)

  1. 为什么我无法取消设置静态属性CORE :: $ ObjClass或self :: $ ObjClass?

好问题。我在unset()的官方文档或静态属性中都没有提到这一点。但是显然你不能。

  1. 使用静态属性执行此操作的正确方法是什么?

您可以将其设置为NULL或一个空数组。

  1. 为什么事件处理程序无法捕获以下错误?

documentation说:

  

以下错误类型无法用用户定义的函数处理:E_ERRORE_PARSEE_CORE_ERRORE_CORE_WARNINGE_COMPILE_ERROR,{{1} },而大多数E_COMPILE_WARNING都在调用E_STRICT的文件中引发。

此错误可能是这些类型之一。我不确定如何确切地知道它的类型。

正在调用关闭函数,但是由于某种原因set_error_handler()返回error_get_last(),而不是有关此错误的信息。

答案 1 :(得分:0)

在文档和在线中进行了大量搜索之后。

尚不清楚为什么错误处理程序无法在__construct__desctruct中正常工作;但是作为一个遥远的主意,我假设即使在解释HTTACCESS文件之前就已经验证了这两个函数,或者即使执行了该文件,指令php_value auto_prepend_file也在两个函数{{1之后执行了}}和__construct已通过验证,这严重破坏了处理错误的方式,并可能导致实现以下解决方案不那么舒适。

首先,我必须实施另一本以前从未阅读过或发现的书,在研究中我发现了它:

__desctruct

而且我想我将不得不执行其他方面的事情。

作为个人发展的第二点:您应该从使用set_exception_handler ("ExeptionHandler"); __construc中的任何方法开始,然后迁移到将所有内容嵌套在声明的方法中。

然后,脚本和结构如下:

HTTACCESS文件(相同):

__destruct

conferror.php(更新为新设置):

php_value auto_prepend_file "./server/conferror.php"

index.php(不变):

<?php
declare(strict_types=1);
ini_set('session.gc_maxlifetime', '0');
ini_set('session.use_only_cookies', '1');
ini_set('session.cookie_httponly', '1');
ini_set('allow_url_fopen', '1');
ini_set('allow_url_include', '1');
ini_set('error_reporting', '1');
ini_set('display_errors', '0');
error_reporting(E_ALL);
register_shutdown_function("ShutdownHandler");
set_error_handler("ErrorHandler");
set_exception_handler("ExeptionHandler");
function ShutdownHandler() {
    $CheckError = error_get_last();
    if ($CheckError != null) {
        $ErrorHandler = "<b>File:</b> " . $CheckError['file'] . '<br>' .
            "<b>Line:</b> " . $CheckError['line'] . '<br>' .
            "<b>Desc:</b> <br>" . $CheckError['message'] . '<br>';
        echo $ErrorHandler;
    }
}
function ErrorHandler($error_level, $error_message, $error_file, $error_line, $error_context) {
    $ErrorHandler = "<b>File:</b> " . $error_file . '<br>' .
        "<b>Line:</b> " . $error_line . '<br>' .
        "<b>Desc:</b> <br>" . $error_message . '<br>';
    echo $ErrorHandler;
}
function ExeptionHandler($e) {
    $ErrorHandler = "<b>File:</b> " . $e->getFile() . '<br>' .
        "<b>Line:</b> " .  $e->getLine() . '<br>' .
        "<b>Desc:</b> <br>" .  $e->getMessage() . '<br>';
    echo $ErrorHandler;
}
?>

要测试的脚本主要(更新:从编程结构中删除<?php require_once 'class.Main.php'; $WebAPP = new CORE(); $WebAPP->Main(); ?> __construct

__destruct

目前,这一切可以完成。如果以后再找到新信息,我会进行更新。