生產環境關閉錯誤顯示 (`display_errors=Off`),嚴重錯誤需第一時間郵件通知管理員介入。
smtp_server=smtp.qq.com smtp_port=465 smtp_ssl=auto auth_username=your_email@qq.com auth_password=your_auth_code force_sender=your_email@qq.com
; 發件人郵箱 sendmail_from = your_email@qq.com ; sendmail 路徑 sendmail_path = "G:\sendmail\sendmail.exe -t"
<?php
// 1. 關閉頁面錯誤顯示
ini_set('display_errors', '0');
// 2. 開啟錯誤日志記錄
ini_set('log_errors', '1');
// ini_set('error_log', 'php_errors.log'); // 可選:指定文件日志
// 3. 記錄所有級別錯誤
error_reporting(E_ALL);
// 4. 發送郵件通知 (error_log 第 2 參數 = 1 表示郵件)
$adminEmail = 'admin@company.com';
$subject = '【生產環境嚴重錯誤】' . date('Y-m-d H:i:s');
$message = "系統檢測到致命錯誤,請立即排查!\n\n";
$message .= "請求 URL: " . ($_SERVER['REQUEST_URI'] ?? 'CLI') . "\n";
$message .= "錯誤信息: " . $errorMessage . "\n";
$message .= "堆棧跟蹤:\n" . $stackTrace . "\n";
// 發送
$sent = error_log($message, 1, $adminEmail, "Subject: $subject\r\nFrom: system@company.com");
if (!$sent) {
// 郵件發送失敗備選:寫入文件、推送釘釘/企微/Slack
file_put_contents(__DIR__ . '/logs/mail_failed.log', date('c') . " $message\n", FILE_APPEND);
}
?>
<?php
// 註冊關閉函數捕獲 E_ERROR/E_PARSE/E_CORE_ERROR 等
register_shutdown_function(function () {
$error = error_get_last();
if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
$msg = "致命錯誤: {$error['message']} in {$error['file']}:{$error['line']}";
error_log($msg, 1, 'admin@company.com', "Subject: [FATAL] PHP Fatal Error");
}
});
// 註冊異常處理器
set_exception_handler(function (Throwable $e) {
$msg = "未捕獲異常: {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}\n{$e->getTraceAsString()}";
error_log($msg, 1, 'admin@company.com', "Subject: [EXCEPTION] Uncaught Exception");
});
// 註冊錯誤處理器 (非致命)
set_error_handler(function ($severity, $message, $file, $line) {
if (!(error_reporting() & $severity)) return false; // 不在報告範圍內
// 只記錄不郵件,避免刷郵箱
error_log("[$severity] $message in $file:$line");
return true; // 不執行內部處理器
});
?>
; php.ini 生產環境核心配置 display_errors = Off display_startup_errors = Off log_errors = On error_log = /var/log/php_errors.log error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT log_errors_max_len = 1024 ignore_repeated_errors = On ignore_repeated_source = On report_memleaks = On track_errors = Off html_errors = Off ; 郵件配置 (Linux 通常用 postfix/sendmail) sendmail_path = /usr/sbin/sendmail -t -i ; Windows 如上文配置
<?php
// 使用 Monolog + SwiftMailer / Symfony Mailer
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\SwiftMailerHandler;
use Monolog\Formatter\HtmlFormatter;
$log = new Logger('app');
$log->pushHandler(new StreamHandler('logs/app.log', Logger::WARNING));
// 郵件處理器:只發 ERROR 以上
$mailer = new Swift_Mailer(new Swift_SmtpTransport('smtp.qq.com', 465, 'ssl'));
$mailHandler = new SwiftMailerHandler($mailer, 'admin@company.com', Logger::ERROR);
$mailHandler->setFormatter(new HtmlFormatter());
$log->pushHandler($mailHandler);
// 使用
$log->error('數據庫連接失敗', ['host' => 'db', 'error' => $e->getMessage()]);
?>
Windows 下 PHP 郵件發送核心在於正確配置 `sendmail.exe` 與 `php.ini`。生產環境建議:
1. 關閉顯示、開啟記錄、全級別報告
2. `register_shutdown_function` 捕獲致命錯誤郵件通知
3. 非致命錯誤僅文件日志,避免郵件風暴
4. 引入 Monolog 等成熟庫實現分級、異步、多通道 (郵件/Slack/釘釘/企微)
5. 定期清理日志文件、監控郵件發送成功率