PHP异常处理程序和关闭函数

PHP异常处理程序和关闭函数,php,exception-handling,Php,Exception Handling,如何捕获(自定义)在自定义关闭函数中抛出的(自定义)异常(使用自定义异常处理程序)?我没有使用任何框架 例如: register_shutdown_function( 'shutdownFunction'); set_exception_handler( 'exceptionHandler'); function exceptionHandler(Exception $exception) { // handle and log exception for later deb

如何捕获(自定义)在自定义关闭函数中抛出的(自定义)异常(使用自定义异常处理程序)?我没有使用任何框架

例如:

register_shutdown_function( 'shutdownFunction');
set_exception_handler(      'exceptionHandler');

function exceptionHandler(Exception $exception)
{
    // handle and log exception for later debugging...
}

function shutdownFunction()
{
    // something is not going right...
    if (someVariable != someValue)
        throw new RuntimeException('blah...'); // WILL NOT be caught by exception handler
}



// somewhere else in the code...
throw new Exception('something...'); // WILL be caught by exception handler (but not in shutdown function)

脚本正在使用异常来传达它在执行过程中遇到错误,即传递给函数的意外变量、数据库未能插入行等。

您可以使用

function shutdownFunction()
    try {
        ...
    } catch (\Exception $e) {
        // do something
    }
}

您将捕获所有异常,因为Exception是所有异常的基类

在php中根本无法做到这一点

register\u shutdown\u函数
回调是PHP应用程序中发生的最后一件事。尝试在其中抛出异常只会调用标准php处理程序。关于这些内部工作原理,在网络上找不到多少

但是,我创建了自己的解决方案,用于将其定向到单个函数

set\u exception\u handler
register\u shutdown\u function
是非常不同的功能:

  • set\u exception\u处理程序
    接收单个参数
    exception
  • register\u shutdown\u函数默认情况下不接收任何参数
我这样做是为了
set\u exception\u处理程序
(接收
$exception
作为参数)设置一个属性,我可以在
register\u shutdown\u函数
中使用该属性

$lastException = null;

set_exception_handler(function ($e) use (&$lastException) {
    $lastException = $e;
});

register_shutdown_function(function() use(&$lastException) {
    if($error = error_get_last()) {
        $lastException = new \ErrorException($error['message'], $error['type'], 1, $error['file'], $error['line']);
    }
    if($lastException) {
        if (APPLICATION_ENV === 'production') {
            Sentry\captureException($lastException);
        } else {
            var_dump($lastException);
        }
    }
});
我不知道这是否是解决问题的好方法,但它允许我在同一个函数中捕获
require unexisting_phpfile1389.php
errors(Fatal)和regular
throw\Exception()
s

尝试在关闭处理程序内引发异常将导致以下异常(多么讽刺):

(!)致命错误:未捕获错误:只能将对象抛出 第34行的C:…\index.php

(!)错误:只能将对象抛出 第34行的C:…\index.php


任何未捕获的异常现在都将转到
exceptionHandler
并终止PHP应用程序。无法从未捕获的异常中恢复。您可以使用
try…catch
blocks捕获错误。我的意思是,我有一个文件,其中包含异常、错误处理和日志记录,每次用户访问任何页面时,它都包含在主脚本中。应用程序流是通过在失败的语句中抛出异常来控制的。在关闭函数之前,一切都是完美的,因为PHP已经(不知何故,不知道)注销了我的异常处理程序,如果我从现在开始抛出任何异常,它将不再被调用。这种拦截PHP错误消息/异常的方法似乎工作得很好,只是它没有得到充实。经过更多测试后,我会发布我的版本作为答案。这种拦截取决于在何处进行;在这种情况下,它是在关机功能中完成的,其中的挑战是独一无二的。设计一个简单但可靠的错误记录系统来代替PHP错误和异常处理,并在各种上下文中处理应用程序检测到的错误,这是一项艰巨的工作。