本文目录导读:

我来详细讲解PHP代码的跟踪和修复方法:
错误日志跟踪
开启错误报告
// 开发环境
error_reporting(E_ALL);
ini_set('display_errors', 1);
// 生产环境 - 记录到日志
error_reporting(E_ALL);
ini_set('display_errors', 0);
ini_set('log_errors', 1);
ini_set('error_log', '/path/to/error.log');
配置 php.ini
error_reporting = E_ALL display_errors = Off log_errors = On error_log = /var/log/php_errors.log
调试工具
Xdebug 调试
# 安装 Xdebug pecl install xdebug # php.ini 配置 [xdebug] zend_extension="xdebug.so" xdebug.mode=debug xdebug.start_with_request=yes xdebug.client_host=127.0.0.1 xdebug.client_port=9003
使用 var_dump 和 print_r
function debug($data, $title = '') {
echo "<pre>";
echo $title ? "<b>$title:</b>\n" : '';
var_dump($data);
echo "</pre>";
}
// 使用示例
$array = ['name' => '张三', 'age' => 25];
debug($array, '用户信息');
异常处理机制
Try-Catch 块
try {
// 可能会出错的代码
$db = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
$result = $db->query('SELECT * FROM users');
} catch (PDOException $e) {
// 捕获特定异常
error_log("数据库错误: " . $e->getMessage());
echo "系统暂时不可用,请稍后再试";
} catch (Exception $e) {
// 捕获一般异常
error_log("系统错误: " . $e->getMessage());
} finally {
// 无论是否异常都执行
$db = null;
}
自定义异常处理
// 设置全局异常处理器
set_exception_handler(function($exception) {
$log = date('Y-m-d H:i:s') . " - " .
$exception->getMessage() .
" in " . $exception->getFile() .
" on line " . $exception->getLine() . "\n";
error_log($log, 3, 'errors.log');
// 友好错误页面
include 'error_page.php';
});
日志记录系统
基础日志函数
class Logger {
private static $logDir = './logs/';
public static function write($message, $level = 'INFO') {
$date = date('Y-m-d H:i:s');
$logFile = self::$logDir . date('Y-m-d') . '.log';
// 创建日志目录
if (!is_dir(self::$logDir)) {
mkdir(self::$logDir, 0755, true);
}
$logEntry = "[$date] [$level] $message" . PHP_EOL;
file_put_contents($logFile, $logEntry, FILE_APPEND | LOCK_EX);
}
public static function error($message) {
self::write($message, 'ERROR');
}
public static function info($message) {
self::write($message, 'INFO');
}
public static function debug($message) {
if (defined('DEBUG_MODE') && DEBUG_MODE) {
self::write($message, 'DEBUG');
}
}
}
// 使用
Logger::error("数据库连接失败: " . $e->getMessage());
Logger::info("用户登录成功: user_id=" . $userId);
使用 Monolog (专业日志库)
// 安装: composer require monolog/monolog
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\RotatingFileHandler;
$log = new Logger('app');
$log->pushHandler(new StreamHandler('app.log', Logger::WARNING));
$log->pushHandler(new RotatingFileHandler('logs/app.log', 7, Logger::DEBUG));
$log->error('数据库错误', ['sql' => $sql, 'error' => $e->getMessage()]);
代码追踪技巧
性能追踪
class Timer {
private static $times = [];
public static function start($name = 'default') {
self::$times[$name] = microtime(true);
}
public static function end($name = 'default') {
if (isset(self::$times[$name])) {
$time = microtime(true) - self::$times[$name];
Logger::info("Timer [$name]: " . round($time, 4) . " seconds");
return $time;
}
return 0;
}
}
// 使用
Timer::start('query');
// 执行数据库查询
Timer::end('query');
函数调用追踪
function trace($message) {
$backtrace = debug_backtrace();
$caller = $backtrace[0];
$file = basename($caller['file']);
$line = $caller['line'];
$function = $caller['function'];
Logger::debug("[$file:$line] $function() - $message");
}
// 使用
function getUser($id) {
trace("获取用户信息: ID=$id");
// ... 代码逻辑
}
实际修复示例
数据库连接问题修复
class Database {
private static $instance = null;
private $connection;
public function __construct() {
try {
$this->connection = new PDO(
"mysql:host=" . DB_HOST . ";dbname=" . DB_NAME,
DB_USER,
DB_PASS,
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
]
);
} catch (PDOException $e) {
Logger::error("数据库连接失败", [
'host' => DB_HOST,
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
throw new Exception("数据库连接失败,请联系管理员");
}
}
}
调试示例
// 修复前的代码
function processData($data) {
$result = [];
foreach ($data as $item) {
$result[] = $item * 2; // $item 不是数字会报错
}
return $result;
}
// 修复后的代码
function processData($data) {
$result = [];
foreach ($data as $index => $item) {
if (!is_numeric($item)) {
Logger::warning("数据项不是数字", [
'index' => $index,
'value' => $item,
'type' => gettype($item)
]);
continue; // 跳过非数字,不中断处理
}
$result[] = $item * 2;
}
return $result;
}
常用调试命令
# 日志实时监控 tail -f /var/log/php_errors.log # 使用 grep 搜索特定错误 grep "PHP Fatal error" /var/log/php_errors.log # PHP 语法检查 php -l your_script.php # 查看 PHP 配置 php -i | grep error
这些方法可以帮助你系统地跟踪和修复PHP代码中的问题,建议在生产环境中使用完善的日志系统,在开发环境中开启详细的错误报告。