PHP Error 和 Logging 函数

Error 和 Logging 函数允许您对错误进行处理和记录,提高应用程序的健壮性和可维护性。

PHP Error 和 Logging 简介

Error 和 Logging 函数允许您对错误进行处理和记录。

Error 函数允许用户定义错误处理规则,并修改记录错误的方式。

Logging 函数允许用户对应用程序进行日志记录,并把日志消息发送到电子邮件、系统日志或其他的机器。

错误处理的重要性

良好的错误处理机制可以帮助:

  • 快速定位和修复问题
  • 提高应用程序的稳定性
  • 记录应用程序的运行状态
  • 改善用户体验

安装说明

Error 和 Logging 函数是 PHP 核心的组成部分。无需安装即可使用这些函数。

检查错误报告级别
// 获取当前错误报告级别
$current_level = error_reporting();
echo "当前错误报告级别: " . $current_level . "\n";

// 显示错误级别名称
echo "错误级别常量: " . getErrorLevelName($current_level);

function getErrorLevelName($level) {
    $levels = [
        E_ERROR => 'E_ERROR',
        E_WARNING => 'E_WARNING',
        E_PARSE => 'E_PARSE',
        E_NOTICE => 'E_NOTICE',
        E_CORE_ERROR => 'E_CORE_ERROR',
        E_CORE_WARNING => 'E_CORE_WARNING',
        E_COMPILE_ERROR => 'E_COMPILE_ERROR',
        E_COMPILE_WARNING => 'E_COMPILE_WARNING',
        E_USER_ERROR => 'E_USER_ERROR',
        E_USER_WARNING => 'E_USER_WARNING',
        E_USER_NOTICE => 'E_USER_NOTICE',
        E_ALL => 'E_ALL',
        E_STRICT => 'E_STRICT',
        E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR',
        E_DEPRECATED => 'E_DEPRECATED',
        E_USER_DEPRECATED => 'E_USER_DEPRECATED'
    ];

    $names = [];
    foreach ($levels as $value => $name) {
        if ($level & $value) {
            $names[] = $name;
        }
    }

    return implode(' | ', $names);
}

PHP Error 和 Logging 函数

函数 描述 版本
debug_backtrace() 生成 backtrace(调试回溯信息)。 PHP 4+
debug_print_backtrace() 打印 backtrace(调试回溯信息)。 PHP 5+
error_get_last() 获得最后发生的错误。 PHP 5+
error_log() 向服务器错误记录、文件或远程目标发送一个错误。 PHP 4+
error_reporting() 规定报告哪个错误。 PHP 4+
restore_error_handler() 恢复之前的错误处理程序。 PHP 4+
restore_exception_handler() 恢复之前的异常处理程序。 PHP 5+
set_error_handler() 设置用户自定义的错误处理函数。 PHP 4+
set_exception_handler() 设置用户自定义的异常处理函数。 PHP 5+
trigger_error() 创建用户自定义的错误消息。 PHP 4+
user_error() trigger_error() 的别名。 PHP 4+
error_clear_last() 清除最后发生的错误。 PHP 7.0+
set_exception_logger() 设置异常记录器。 PHP 8.1+
get_error_context() 获取错误发生的上下文信息。 PHP 8.2+

PHP Error 和 Logging 常量

常量 描述 版本
1 E_ERROR 运行时致命的错误。不能修复的错误。停止执行脚本。 PHP 4+
2 E_WARNING 运行时非致命的错误。没有停止执行脚本。 PHP 4+
4 E_PARSE 编译时的解析错误。解析错误应该只由解析器生成。 PHP 4+
8 E_NOTICE 运行时的通知。脚本发现可能是一个错误,但也可能在正常运行脚本时发生。 PHP 4+
16 E_CORE_ERROR PHP 启动时的致命错误。这就如同 PHP 核心的 E_ERROR。 PHP 4+
32 E_CORE_WARNING PHP 启动时的非致命错误。这就如同 PHP 核心的 E_WARNING。 PHP 4+
64 E_COMPILE_ERROR 编译时致命的错误。这就如同由 Zend 脚本引擎生成的 E_ERROR。 PHP 4+
128 E_COMPILE_WARNING 编译时非致命的错误。这就如同由 Zend 脚本引擎生成的 E_WARNING。 PHP 4+
256 E_USER_ERROR 用户生成的致命错误。这就如同由程序员使用 PHP 函数 trigger_error() 生成的 E_ERROR。 PHP 4+
512 E_USER_WARNING 用户生成的非致命错误。这就如同由程序员使用 PHP 函数 trigger_error() 生成的 E_WARNING。 PHP 4+
1024 E_USER_NOTICE 用户生成的通知。这就如同由程序员使用 PHP 函数 trigger_error() 生成的 E_NOTICE。 PHP 4+
2048 E_STRICT 运行时的通知。PHP 建议您改变代码,以提高代码的互用性和兼容性。 PHP 5+
4096 E_RECOVERABLE_ERROR 可捕获的致命错误。这就如同一个可以由用户定义的句柄捕获的 E_ERROR(见 set_error_handler())。 PHP 5+
8192 E_DEPRECATED 运行时通知。启用后将会对在未来版本中可能无法正常工作的代码给出警告。 PHP 5.3+
16384 E_USER_DEPRECATED 用户产生的警告信息。类似于 E_DEPRECATED,但是是由用户使用 trigger_error() 函数产生的。 PHP 5.3+
32767 E_ALL 所有的错误和警告的级别(PHP 5.4+ 包括 E_STRICT)。 PHP 5+

使用示例

自定义错误处理
// 自定义错误处理函数
function customErrorHandler($errno, $errstr, $errfile, $errline) {
    switch ($errno) {
        case E_USER_ERROR:
            echo "<b>我的错误</b> [$errno] $errstr<br>\n";
            echo "  错误发生在第 $errline 行的 $errfile 文件中<br>\n";
            echo "  PHP版本 " . PHP_VERSION . " (" . PHP_OS . ")<br>\n";
            echo "终止执行...<br>\n";
            exit(1);
            break;

        case E_USER_WARNING:
            echo "<b>我的警告</b> [$errno] $errstr<br>\n";
            break;

        case E_USER_NOTICE:
            echo "<b>我的通知</b> [$errno] $errstr<br>\n";
            break;

        default:
            echo "未知错误类型: [$errno] $errstr<br>\n";
            break;
    }

    // 记录到日志文件
    error_log(date('[Y-m-d H:i:s]') . " [$errno] $errstr 在 $errfile 的第 $errline 行", 3, "error.log");

    // 不执行PHP内置的错误处理
    return true;
}

// 设置错误处理函数
set_error_handler("customErrorHandler");

// 触发错误
$test = 2;
if ($test > 1) {
    trigger_error("自定义错误消息", E_USER_WARNING);
}
异常处理
// 自定义异常处理函数
function customExceptionHandler($exception) {
    echo "未捕获的异常: " . $exception->getMessage() . "\n";
    echo "异常发生在文件: " . $exception->getFile() . "\n";
    echo "异常发生在行数: " . $exception->getLine() . "\n";

    // 记录异常到日志文件
    $logMessage = sprintf(
        "[%s] 异常: %s 在 %s 的第 %d 行\n栈跟踪:\n%s\n",
        date('Y-m-d H:i:s'),
        $exception->getMessage(),
        $exception->getFile(),
        $exception->getLine(),
        $exception->getTraceAsString()
    );

    error_log($logMessage, 3, 'exceptions.log');
}

// 设置异常处理函数
set_exception_handler('customExceptionHandler');

// 抛出异常
throw new Exception("这是一个测试异常");

// 恢复默认异常处理程序
restore_exception_handler();
调试和日志记录
// 调试回溯
function testFunction() {
    anotherFunction();
}

function anotherFunction() {
    // 获取调试回溯
    $backtrace = debug_backtrace();
    echo "调试回溯:\n";
    print_r($backtrace);

    // 或者直接打印
    echo "\n打印调试回溯:\n";
    debug_print_backtrace();
}

// 调用函数
testFunction();

// 记录错误到不同目标
echo "\n错误日志示例:\n";

// 记录到系统日志
error_log("这是一条系统日志", 0);

// 记录到文件
error_log("这是一条文件日志\n", 3, "my-errors.log");

// 发送到邮箱(需要配置)
// error_log("这是一条邮件日志", 1, "admin@example.com");

// 记录到远程服务器
// error_log("这是一条远程日志", 2, "udp://logs.example.com:1234");

// 获取最后发生的错误
@$undefined; // 产生一个错误
$last_error = error_get_last();
echo "\n最后发生的错误:\n";
print_r($last_error);
错误报告级别设置
// 显示所有错误
error_reporting(E_ALL);

// 显示所有错误除了通知
error_reporting(E_ALL & ~E_NOTICE);

// 只显示致命错误和警告
error_reporting(E_ERROR | E_WARNING);

// 在生产环境中推荐设置
ini_set('display_errors', 0);
ini_set('log_errors', 1);
ini_set('error_log', '/path/to/php-error.log');
error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT);

// 在开发环境中推荐设置
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

// 检查是否在开发环境
if (defined('ENVIRONMENT')) {
    if (ENVIRONMENT == 'development') {
        error_reporting(E_ALL);
        ini_set('display_errors', 1);
    } else {
        error_reporting(0);
        ini_set('display_errors', 0);
    }
}
最佳实践
  • 在开发环境中启用错误显示,在生产环境中禁用错误显示
  • 使用自定义错误处理函数来统一处理错误
  • 将错误记录到日志文件中以便后续分析
  • 使用异常处理来处理可预见的错误情况
  • 在代码的关键部分添加适当的错误检查和日志记录
  • 定期检查和分析错误日志
  • 使用适当的错误报告级别(E_ALL 用于开发,生产环境减少不必要的错误报告)
安全注意事项
  • 生产环境禁止显示错误信息:避免泄露敏感信息
  • 安全记录错误:确保错误日志文件不被公开访问
  • 过滤用户输入:避免将未经处理的用户输入记录到日志中
  • 定期清理日志:防止日志文件过大导致问题
  • 权限控制:确保只有授权人员可以访问错误日志