本文目录导读:

我来详细介绍 PHP 错误收集的几种方法:
基础错误处理函数
使用 set_error_handler()
// 设置自定义错误处理函数
set_error_handler(function($errno, $errstr, $errfile, $errline) {
$error = [
'type' => $errno,
'message' => $errstr,
'file' => $errfile,
'line' => $errline,
'time' => date('Y-m-d H:i:s')
];
// 记录到文件
file_put_contents('error.log', json_encode($error) . PHP_EOL, FILE_APPEND);
// 返回 true 阻止 PHP 内置错误处理
return true;
});
使用 set_exception_handler()
// 处理未捕获的异常
set_exception_handler(function($exception) {
$error = [
'type' => 'Exception',
'message' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'trace' => $exception->getTraceAsString(),
'time' => date('Y-m-d H:i:s')
];
// 记录到文件或发送到监控系统
file_put_contents('exception.log', json_encode($error) . PHP_EOL, FILE_APPEND);
});
完整的错误监控方案
类封装示例
class ErrorCollector {
private static $instance = null;
private $logDir;
private $isRegistered = false;
private function __construct($logDir = null) {
$this->logDir = $logDir ?: __DIR__ . '/logs';
if (!is_dir($this->logDir)) {
mkdir($this->logDir, 0777, true);
}
}
public static function getInstance($logDir = null) {
if (self::$instance === null) {
self::$instance = new self($logDir);
}
return self::$instance;
}
public function register() {
if ($this->isRegistered) return;
set_error_handler([$this, 'handleError']);
set_exception_handler([$this, 'handleException']);
register_shutdown_function([$this, 'handleShutdown']);
$this->isRegistered = true;
}
public function handleError($errno, $errstr, $errfile, $errline) {
$error = [
'type' => $this->getErrorType($errno),
'code' => $errno,
'message' => $errstr,
'file' => $errfile,
'line' => $errline,
'time' => date('Y-m-d H:i:s'),
'ip' => $_SERVER['REMOTE_ADDR'] ?? 'CLI',
'url' => $_SERVER['REQUEST_URI'] ?? 'CLI'
];
$this->logError($error);
// 不阻止 PHP 内置错误处理
return false;
}
public function handleException($exception) {
$error = [
'type' => 'Exception',
'code' => $exception->getCode(),
'message' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'trace' => $exception->getTraceAsString(),
'time' => date('Y-m-d H:i:s'),
'ip' => $_SERVER['REMOTE_ADDR'] ?? 'CLI',
'url' => $_SERVER['REQUEST_URI'] ?? 'CLI'
];
$this->logError($error);
}
public function handleShutdown() {
$error = error_get_last();
if ($error !== null && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
$this->handleError($error['type'], $error['message'], $error['file'], $error['line']);
}
}
private function logError($error) {
// 按日期分类存储
$filename = $this->logDir . '/error_' . date('Y-m-d') . '.log';
$logEntry = json_encode($error, JSON_UNESCAPED_UNICODE) . PHP_EOL;
file_put_contents($filename, $logEntry, FILE_APPEND);
// 错误级别较高时发送通知
if ($this->isCriticalError($error['code'])) {
$this->sendAlert($error);
}
}
private function getErrorType($errno) {
$types = [
E_ERROR => 'Fatal Error',
E_WARNING => 'Warning',
E_PARSE => 'Parse Error',
E_NOTICE => 'Notice',
E_CORE_ERROR => 'Core Error',
E_COMPILE_ERROR => 'Compile Error',
E_USER_ERROR => 'User Error',
E_USER_WARNING => 'User Warning',
E_USER_NOTICE => 'User Notice',
E_STRICT => 'Strict',
E_RECOVERABLE_ERROR => 'Recoverable Error',
E_DEPRECATED => 'Deprecated',
E_USER_DEPRECATED => 'User Deprecated'
];
return $types[$errno] ?? 'Unknown';
}
private function isCriticalError($code) {
return in_array($code, [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR]);
}
private function sendAlert($error) {
// 实现发送警报的逻辑(邮件、短信、Webhook等)
// mail('admin@example.com', 'Critical Error', print_r($error, true));
}
}
// 使用示例
$collector = ErrorCollector::getInstance(__DIR__ . '/logs');
$collector->register();
使用第三方库
Monolog (推荐)
composer require monolog/monolog
// 使用示例
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\NativeMailerHandler;
use Monolog\Processor\WebProcessor;
$log = new Logger('app');
$log->pushHandler(new StreamHandler(__DIR__ . '/logs/app.log', Logger::WARNING));
$log->pushHandler(new NativeMailerHandler('admin@example.com', 'Error Alert', 'from@example.com', Logger::CRITICAL));
$log->pushProcessor(new WebProcessor());
// 记录错误
try {
// 你的代码
} catch (\Exception $e) {
$log->error('Error occurred: ' . $e->getMessage(), [
'trace' => $e->getTraceAsString(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
Whoops (开发环境)
composer require filp/whoops // 使用示例 $whoops = new \Whoops\Run; $whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler); $whoops->register();
生产环境最佳实践
// 配置文件 config.php
return [
'error_handler' => [
'enabled' => true,
'log_dir' => __DIR__ . '/../logs',
'log_level' => E_ALL & ~E_DEPRECATED & ~E_STRICT,
'display_errors' => false,
'send_alerts' => true,
'alert_email' => 'admin@example.com',
'alert_level' => E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR,
]
];
// 初始化
$config = require 'config.php';
$collector = ErrorCollector::getInstance($config['error_handler']['log_dir']);
$collector->register();
// 设置 PHP 配置
ini_set('display_errors', $config['error_handler']['display_errors'] ? '1' : '0');
ini_set('log_errors', '1');
ini_set('error_log', $config['error_handler']['log_dir'] . '/php_errors.log');
error_reporting($config['error_handler']['log_level']);
错误收集工具集成
// Sentry 集成
// composer require sentry/sdk
\Sentry\init(['dsn' => 'your-sentry-dsn' ]);
// 自动捕获所有错误
\Sentry\configureScope(function (\Sentry\State\Scope $scope): void {
$scope->setUser(['email' => 'user@example.com']);
});
set_error_handler(function($severity, $message, $file, $line) {
throw new \ErrorException($message, 0, $severity, $file, $line);
});
// 或者使用框架集成(Laravel)
if (app()->bound('sentry')) {
$this->app->make('sentry');
}
自定义错误格式
// 支持多格式输出
class ErrorFormatter {
public static function toJson($error) {
return json_encode($error, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
}
public static function toText($error) {
return sprintf(
"[%s] %s: %s in %s on line %d\nURL: %s\nIP: %s\n",
$error['time'],
$error['type'],
$error['message'],
$error['file'],
$error['line'],
$error['url'],
$error['ip']
);
}
public static function toHtml($error) {
return sprintf(
'<div class="error-entry">
<h3>%s</h3>
<p><strong>Time:</strong> %s</p>
<p><strong>Message:</strong> %s</p>
<p><strong>File:</strong> %s:%d</p>
</div>',
$error['type'],
$error['time'],
htmlspecialchars($error['message']),
htmlspecialchars($error['file']),
$error['line']
);
}
}
建议
- 开发环境:显示详细错误信息
- 生产环境:记录错误但不显示,使用日志和监控系统
- 使用成熟的库:Monolog, Sentry, Bugsnag等
- 定期检查日志:设置日志轮转和清理策略
- 错误分级:根据严重程度发送不同级别的通知
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播