发生中断错误


#触发时机:程序执行完成,活着Fatal Error程序中断
register_shutdown_function('debug_error',debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS));
//调试错误信息
if(!function_exists('debug_error'))
{
    $GLOBALS['argv']=$argv;
    $GLOBALS['argc']=$argc;
    $GLOBALS['_server']=$_SERVER;
    function debug_error($backtraceList=[])
    {
        $lastError=error_get_last();
        if(!is_null($lastError))
        {
            $errorMessage=$backtrace = "";
            $errorMessage.="【错误类型】:{$lastError['type']}。【错误信息】:{$lastError['message']}。【出错文件】:{$lastError['file']}。【文件行数】:{$lastError['line']}。";
            if(is_array($backtraceList) && !empty($backtraceList))
            {
                foreach ($backtraceList as $v)
                {
                    $backtrace .= "{$v['file']} - {$v['line']} - {$v['class']}::{$v['function']}()".'。';
                }
            }

            $errorMessage.="【调用堆栈】:{$backtrace}";

            //显示访问路径
            $sapiName = php_sapi_name();
            if($sapiName !== false)
            {
                if($sapiName != 'cli')
                {
                    //http请求方式
                    if(!empty($GLOBALS['_server']))
                    {
                        $httpReferer = isset($GLOBALS['_server']['HTTP_REFERER']) ? $GLOBALS['_server']['HTTP_REFERER'] : '-';
                        $httpHost = isset($GLOBALS['_server']['HTTP_HOST']) ? $GLOBALS['_server']['HTTP_HOST'] : '-';
                        $scriptUrl = isset($GLOBALS['_server']['SCRIPT_URL']) ? $GLOBALS['_server']['SCRIPT_URL'] : '-';
                        $queryString = isset($GLOBALS['_server']['QUERY_STRING']) ? $GLOBALS['_server']['QUERY_STRING'] : '-';
                        $errorMessage.="【上级URL】:{$httpReferer}。【当前URL】:{$httpHost}{$scriptUrl}?{$queryString}。【script】:{$scriptUrl}。";
                    }
                }
                else
                {
                    // 后面的参数
                    $paramString="";
                    for ($i=2; $i<$GLOBALS['argc']; $i++)
                    {
                        $paramString.=" {$GLOBALS['argv'][$i]} ";
                    }
                    //$errorMessage .= "【CLI请求路由参数】{$paramString} ";

                    //cli请求方式
                    $errorMessage .= "【CLI请求】{$GLOBALS['argv'][0]} {$GLOBALS['argv'][1]} {$paramString}";
                }
            }

            $errorMessage = str_replace(array("\r\n", "\r", "\n","   "), '', $errorMessage);
            error_log("CUSTOM_ERROR".$errorMessage);
            unset($errorMessage,$backtrace);
        }
    }
}

swoole提供的参考写法

register_shutdown_function('handleFatal');

function handleFatal()
{
    $error = error_get_last();
    switch ($error['type'] ?? null) {
        case E_ERROR :
        case E_PARSE :
        case E_CORE_ERROR :
        case E_COMPILE_ERROR :
            $message = $error['message'] . PHP_EOL;
            if (isset($_SERVER['REQUEST_URI'])) {
                $message .= '[QUERY] ' . $_SERVER['REQUEST_URI'];
            }
            // log or send:
            // error_log($message);
            // $server->send($fd, $message);
            break;
    }
}

发生错误


set_error_handler('debug_error2');
#trigger_error($errorMessage,E_USER_ERROR);
#restore_error_handler();
if(!function_exists('debug_error2'))
{
    $GLOBALS['argv']=$argv;
    $GLOBALS['argc']=$argc;
    $GLOBALS['_server']=$_SERVER;
    function debug_error2($errno, $errstr, $errfile, $errline)
    {
	if(!in_array($errno,[E_ERROR,E_WARNING,E_PARSE,E_CORE_ERROR,E_CORE_WARNING,E_COMPILE_ERROR,E_COMPILE_WARNING,E_USER_ERROR,E_USER_WARNING,E_RECOVERABLE_ERROR]))
        {
            return;
        }
        $errorMessage = '';
        $backtrace = '-';

        if(strpos($errstr,'Smarty Exception') !== false)
        {
            $errfile = $errline = '-';
        }

        //增加符号转义,解决告警时因符号原因内容截取不全。
        $errstr = addslashes($errstr);

        $errorMessage .= "【错误编号】:{$errno}。【错误信息】:{$errstr}。【出错文件】:{$errfile}。【文件行数】:{$errline}。";

        $backtraceList = '';
        if(is_array($backtraceList) && !empty($backtraceList))
        {
            foreach ($backtraceList as $v)
            {
                $backtrace .= "{$v['file']} - {$v['line']} - {$v['class']}::{$v['function']}()".'。';
            }
        }

        $errorMessage.="【调用堆栈】:{$backtrace}";

        //显示访问路径
        $sapiName = php_sapi_name();
        if($sapiName !== false)
        {
            if($sapiName != 'cli')
            {
                //http请求方式
                if(!empty($GLOBALS['_server']))
                {
                    $httpReferer = isset($GLOBALS['_server']['HTTP_REFERER']) ? $GLOBALS['_server']['HTTP_REFERER'] : '-';
                    $httpHost = isset($GLOBALS['_server']['HTTP_HOST']) ? $GLOBALS['_server']['HTTP_HOST'] : '-';
                    $scriptUrl = isset($GLOBALS['_server']['SCRIPT_URL']) ? $GLOBALS['_server']['SCRIPT_URL'] : '-';
                    $queryString = isset($GLOBALS['_server']['QUERY_STRING']) ? $GLOBALS['_server']['QUERY_STRING'] : '-';
                    $errorMessage.="【上级URL】:{$httpReferer}。【当前URL】:{$httpHost}{$scriptUrl}?{$queryString}。【script】:{$scriptUrl}。";
                }
            }
            else
            {
                // 后面的参数
                $paramString="";
                for ($i=2; $i<$GLOBALS['argc']; $i++)
                {
                    $paramString.=" {$GLOBALS['argv'][$i]} ";
                }
                //$errorMessage .= "【CLI请求路由参数】{$paramString} ";

                //cli请求方式
                $errorMessage .= "【CLI请求】{$GLOBALS['argv'][0]} {$GLOBALS['argv'][1]} {$paramString}";
            }
        }

        $errorMessage = str_replace(array("\r\n", "\r", "\n","   "), '', $errorMessage);
        error_log("CUSTOM_ERROR".$errorMessage);
        unset($errorMessage,$backtrace);

        return true;
    }

}