代码调试技巧
调试是开发中必不可少的技能,本文介绍 PHP 中常用的调试方法。
基础调试输出
php
// print_r 和 var_dump
$arr = ['a' => 1, 'b' => 2];
print_r($arr);
var_dump($arr); // 更详细,包含类型信息
// 格式化输出
var_export($arr); // 可直接作为 PHP 代码使用
// 输出并终止(最常用)
var_dump($data);
die(); // 或 exit()
// 美化 var_dump(需要 Xdebug)
ini_set('xdebug.var_display_max_depth', 10);
ini_set('xdebug.var_display_max_children', 256);
ini_set('xdebug.var_display_max_data', 1024);日志调试
php
// 错误日志
error_log('调试信息');
error_log('变量值: ' . print_r($var, true));
// 自定义日志函数
function debug_log($message, $data = null) {
$log = [
'time' => date('Y-m-d H:i:s'),
'file' => debug_backtrace()[0]['file'],
'line' => debug_backtrace()[0]['line'],
'message' => $message,
'data' => $data
];
error_log(json_encode($log, JSON_UNESCAPED_UNICODE) . "\n", 3, '/tmp/debug.log');
}
// 使用
debug_log('用户登录', ['user_id' => 123]);调试函数
php
// 获取调用栈
debug_print_backtrace();
// 获取更详细的信息
$trace = debug_backtrace();
foreach ($trace as $frame) {
echo $frame['file'] . ':' . $frame['line'] . ' ' . $frame['function'] . "\n";
}
// 获取内存使用
echo memory_get_usage() . " bytes\n";
echo memory_get_peak_usage() . " bytes\n";
// 获取执行时间
$start = microtime(true);
// ... 代码 ...
echo '耗时: ' . (microtime(true) - $start) . ' 秒';断点调试(Xdebug)
php
// 触发断点
xdebug_break();
// 配置 php.ini
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=localhost
xdebug.client_port=9003
xdebug.idekey=PHPSTORM使用 VS Code + PHP Debug 扩展:
- 安装 PHP Debug 扩展
- 创建
.vscode/launch.json配置 - 设置断点并按 F5 启动调试
json
{
"version": "0.2.0",
"configurations": [
{
"name": "Listen for Xdebug",
"type": "php",
"request": "launch",
"port": 9003
}
]
}调试工具类
php
class Debugger {
private static $timers = [];
private static $logs = [];
// 开始计时
public static function start($name) {
self::$timers[$name] = microtime(true);
}
// 结束计时
public static function end($name) {
if (!isset(self::$timers[$name])) return null;
$time = microtime(true) - self::$timers[$name];
unset(self::$timers[$name]);
return round($time * 1000, 2) . 'ms';
}
// 记录变量
public static function log($key, $value) {
self::$logs[$key] = $value;
}
// 显示所有调试信息
public static function dump() {
echo "<pre style='background:#333;color:#fff;padding:10px;'>";
echo "=== Debug Output ===\n\n";
foreach (self::$logs as $key => $value) {
echo "[$key]:\n";
var_export($value);
echo "\n\n";
}
echo "</pre>";
}
}
// 使用
Debugger::start('query');
$result = $db->query($sql);
Debugger::end('query');
Debugger::log('result', $result);
Debugger::dump();异常调试
php
try {
$result = riskyOperation();
} catch (Exception $e) {
echo "错误: " . $e->getMessage() . "\n";
echo "文件: " . $e->getFile() . "\n";
echo "行号: " . $e->getLine() . "\n";
echo "堆栈:\n" . $e->getTraceAsString() . "\n";
}注意事项
- 生产环境不要暴露
display_errors - 调试代码要及时清理,不要提交到版本控制
- 使用日志文件调试 API 接口
- 复杂问题使用 Xdebug 断点调试更高效