本文目录导读:

我来详细介绍 PHP 错误日志记录的几种方法:
php.ini 配置
基本配置
# 开启错误日志 log_errors = On # 指定错误日志文件路径 error_log = /var/log/php_errors.log # 设置错误报告级别 error_reporting = E_ALL & ~E_NOTICE & ~E_DEPRECATED # 显示错误(开发环境开启,生产环境关闭) display_errors = Off # 记录最大错误数 log_errors_max_len = 1024
常用错误级别
// 所有错误 error_reporting(E_ALL); // 除了提示信息 error_reporting(E_ALL & ~E_NOTICE); // 严格模式(推荐) error_reporting(E_ALL | E_STRICT);
运行时设置错误日志
// 开启错误日志
ini_set('log_errors', 1);
// 设置日志文件路径
ini_set('error_log', '/path/to/error.log');
// 设置错误报告级别
ini_set('error_reporting', E_ALL);
使用 error_log() 函数
// 简单记录
error_log("发生了一个错误");
// 记录到指定文件
error_log("数据库连接失败", 3, "/var/log/db_errors.log");
// 发送到系统日志
error_log("系统错误", 0);
// 发送到邮件(不推荐)
error_log("严重错误", 1, "[email protected]");
自定义错误处理函数
// 自定义错误处理
function customErrorHandler($errno, $errstr, $errfile, $errline) {
$logMessage = sprintf(
"[%s] 错误级别: %d - %s 在文件 %s 第 %d 行\n",
date('Y-m-d H:i:s'),
$errno,
$errstr,
$errfile,
$errline
);
// 写入日志
error_log($logMessage, 3, '/var/log/custom_errors.log');
// 返回 true 阻止 PHP 默认错误处理
return true;
}
// 注册自定义错误处理器
set_error_handler("customErrorHandler");
使用异常处理记录错误
try {
// 可能出错的代码
$result = 10 / 0;
} catch (Exception $e) {
// 记录错误信息
error_log("捕获异常: " . $e->getMessage());
error_log("文件: " . $e->getFile() . " 行: " . $e->getLine());
}
完整的日志类示例
class Logger {
private $logFile;
private $logLevel;
const DEBUG = 1;
const INFO = 2;
const WARNING = 3;
const ERROR = 4;
public function __construct($logFile, $logLevel = self::INFO) {
$this->logFile = $logFile;
$this->logLevel = $logLevel;
}
public function log($message, $level = self::INFO) {
if ($level < $this->logLevel) {
return;
}
$levelNames = [
self::DEBUG => 'DEBUG',
self::INFO => 'INFO',
self::WARNING => 'WARNING',
self::ERROR => 'ERROR'
];
$logMessage = sprintf(
"[%s] [%s] %s\n",
date('Y-m-d H:i:s'),
$levelNames[$level],
$message
);
error_log($logMessage, 3, $this->logFile);
}
public function debug($message) {
$this->log($message, self::DEBUG);
}
public function info($message) {
$this->log($message, self::INFO);
}
public function warning($message) {
$this->log($message, self::WARNING);
}
public function error($message) {
$this->log($message, self::ERROR);
}
}
// 使用示例
$logger = new Logger('/var/log/app.log', Logger::INFO);
$logger->debug("这条不会被记录");
$logger->info("应用启动成功");
$logger->warning("内存使用过高");
$logger->error("数据库连接失败");
日志文件管理
class LogManager {
private $logFile;
private $maxSize;
private $backupCount;
public function __construct($logFile, $maxSize = 10485760, $backupCount = 5) {
$this->logFile = $logFile;
$this->maxSize = $maxSize;
$this->backupCount = $backupCount;
}
public function write($message) {
// 检查文件大小并轮转
$this->rotateIfNeeded();
return error_log($message, 3, $this->logFile);
}
private function rotateIfNeeded() {
if (!file_exists($this->logFile)) {
return;
}
if (filesize($this->logFile) < $this->maxSize) {
return;
}
// 删除最旧的备份
$oldestBackup = $this->logFile . '.' . $this->backupCount;
if (file_exists($oldestBackup)) {
unlink($oldestBackup);
}
// 重命名现有备份
for ($i = $this->backupCount - 1; $i >= 1; $i--) {
$oldFile = $this->logFile . '.' . $i;
$newFile = $this->logFile . '.' . ($i + 1);
if (file_exists($oldFile)) {
rename($oldFile, $newFile);
}
}
// 重命名当前日志文件
rename($this->logFile, $this->logFile . '.1');
}
}
最佳实践
// 生产环境配置
ini_set('display_errors', 0);
ini_set('log_errors', 1);
ini_set('error_reporting', E_ALL & ~E_NOTICE & ~E_STRICT);
// 记录带上下文的错误
$context = [
'user_id' => 123,
'ip' => $_SERVER['REMOTE_ADDR'],
'url' => $_SERVER['REQUEST_URI']
];
error_log("登录失败,上下文:" . json_encode($context));
// 使用框架的日志系统(如 Monolog)
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
$logger = new Logger('app');
$logger->pushHandler(new StreamHandler('/var/log/app.log', Logger::WARNING));
$logger->error('数据库错误', ['exception' => $e]);
注意事项
- 确保日志目录可写
- 生产环境关闭 display_errors
- 定期清理日志文件
- 考虑日志分级
- 敏感信息不要记录日志
- 使用日志轮转避免文件过大
这样就能有效地记录和管理 PHP 错误日志了。