0Pricing
PHP Academy · 课时

记录错误与最佳实践

将错误记录到文件,并遵循生产环境中的错误处理模式。

记录错误与最佳实践 是 CoddyKit 上的免费 PHP Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 PHP Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 PHP Academy 课程共包含 4 节课。

日志记录为何重要

在生产环境中,您不能向用户显示错误,但仍需要知道何时出现问题。日志记录会将错误详情保存到文件或服务中,以便您稍后进行调查。

error_log()

最简单的日志记录函数 — 将消息写入 PHP 的错误日志:

<?php
error_log('User login failed for: ' . $email);
error_log('DB query took: ' . $duration . 'ms');

// Send to email (not recommended for high traffic)
error_log('Critical: server out of memory', 1, 'admin@example.com');

结构化日志记录

将结构化数据记录为 JSON,以便更轻松地解析和查询:

<?php
function logEvent(string $level, string $message, array $context = []): void {
    $entry = array_merge([
        'ts'      => date('c'),
        'level'   => $level,
        'message' => $message,
    ], $context);

    error_log(json_encode($entry));
}

logEvent('ERROR', 'Payment failed', [
    'order_id' => 123,
    'amount'   => 99.99,
    'user_id'  => 45,
]);

日志级别(PSR-3)

PSR-3 定义了标准日志级别:

  • emergency — 系统无法使用
  • alert — 必须采取行动
  • critical — 严重情况
  • error — 运行时错误
  • warning — 并非错误的异常情况
  • notice — 正常但重要的事件
  • info — 信息性消息
  • debug — 详细的调试信息

Monolog 日志记录器

Monolog 是 PHP 的标准日志记录库,与 PSR-3 兼容:

<?php
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

$log = new Logger('app');
$log->pushHandler(new StreamHandler('/var/log/app.log', Logger::DEBUG));

$log->info('User logged in', ['user_id' => 42]);
$log->error('Payment failed', ['order' => 99, 'reason' => 'card_declined']);
$log->warning('Slow query', ['duration_ms' => 3200]);

生产环境中的异常处理

一个适用于生产环境的异常处理器,它会记录异常并返回安全的响应:

<?php
set_exception_handler(function(\Throwable $e) {
    $id = uniqid('err_');
    error_log(json_encode([
        'error_id' => $id,
        'class'    => get_class($e),
        'message'  => $e->getMessage(),
        'file'     => $e->getFile(),
        'line'     => $e->getLine(),
        'trace'    => $e->getTraceAsString(),
    ]));
    http_response_code(500);
    echo json_encode(['error' => 'Server error', 'id' => $id]);
    exit(1);
});

日志轮换

日志文件会无限增长 — 在 Linux 中使用 logrotate,或在 Monolog 中使用基于时间的处理器来轮换日志:

<?php
use Monolog\Handler\RotatingFileHandler;

$handler = new RotatingFileHandler(
    '/var/log/app.log',
    30,              // keep 30 days
    Logger::DEBUG
);

// Creates dated files: app-2024-05-27.log
$log = new Logger('app');
$log->pushHandler($handler);

包含丰富上下文的日志记录

在每条日志记录中包含请求上下文,以便更轻松地调试:

<?php
function getRequestContext(): array {
    return [
        'url'     => $_SERVER['REQUEST_URI'] ?? '',
        'method'  => $_SERVER['REQUEST_METHOD'] ?? '',
        'ip'      => $_SERVER['REMOTE_ADDR'] ?? '',
        'user_id' => $_SESSION['user_id'] ?? null,
    ];
}

// Add to every log call:
$log->error('Order failed', array_merge(
    getRequestContext(),
    ['order_id' => $orderId]
));

避免在日志中记录敏感数据

绝不要记录敏感信息:

  • 密码和令牌
  • 信用卡号
  • 个人数据(符合 GDPR 要求)
  • 面向用户的响应中的完整异常调用栈
<?php
// Bad:
error_log('Login attempt: ' . $email . ' / ' . $password);

// Good:
error_log('Login failed for user: ' . substr($email, 0, 3) . '***');

Sentry 与外部错误跟踪

在生产环境中,使用 Sentry 等错误跟踪服务集中管理错误并发出提醒:

<?php
// After composer require sentry/sdk
\Sentry\init(['dsn' => getenv('SENTRY_DSN')]);

// Automatic capture of unhandled exceptions
// Manual capture:
try {
    processOrder();
} catch (\Throwable $e) {
    \Sentry\captureException($e);
    throw $e;
}

基于断言的前置条件

使用断言在开发过程中捕获程序错误:

<?php
// assert() throws AssertionError when false (dev mode)
assert(is_int($userId), 'userId must be an integer');
assert($amount > 0, 'amount must be positive');

// Or throw explicitly:
if (!is_int($userId)) {
    throw new \InvalidArgumentException('userId must be int');
}

快速检查

根据 PSR-3,哪个日志级别表示需要立即关注的情况?

回顾:错误日志记录

日志记录最佳实践:

  • 使用包含时间戳、级别、消息和上下文的结构化 JSON 日志
  • 遵循 PSR-3 日志级别
  • 在生产应用程序中使用 Monolog
  • 轮换日志,防止磁盘空间耗尽
  • 绝不要记录密码或敏感数据
  • 使用 Sentry 或类似工具进行实时错误跟踪

常见问题解答

「记录错误与最佳实践」课时是免费的吗?

是的 — 「记录错误与最佳实践」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 PHP Academy 课程的其余内容,请升级到 CoddyKit PRO。 PHP Academy 课程共包含 4 节课。

「记录错误与最佳实践」这节课中我会学到什么?

将错误记录到文件,并遵循生产环境中的错误处理模式。 你通过在浏览器中直接运行的动手代码来练习 PHP Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 PHP Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 PHP Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「记录错误与最佳实践」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 PHP Academy 课中编写并运行代码吗?

能。每节 PHP Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. PHP 错误类型与报告
  2. Try、Catch 与 Finally
  3. 创建自定义异常
  4. 记录错误与最佳实践
← 返回 PHP Academy