本文目录导读:

在 PHP 中进行 HTTP 调试,有多种方法和工具,以下是系统化的调试方案:
基础调试方法
打印请求信息
<?php
// 查看所有请求头
print_r(getallheaders());
// 查看请求方法
echo $_SERVER['REQUEST_METHOD'];
// 查看请求体
$requestBody = file_get_contents('php://input');
echo $requestBody;
// 查看GET参数
print_r($_GET);
// 查看POST参数
print_r($_POST);
?>
创建调试函数
<?php
function debugRequest() {
$debug = [
'method' => $_SERVER['REQUEST_METHOD'],
'uri' => $_SERVER['REQUEST_URI'],
'headers' => getallheaders(),
'get' => $_GET,
'post' => $_POST,
'cookies' => $_COOKIE,
'body' => file_get_contents('php://input')
];
// 输出到日志文件
file_put_contents('debug.log',
date('Y-m-d H:i:s') . ' ' .
json_encode($debug, JSON_PRETTY_PRINT) . "\n",
FILE_APPEND
);
}
?>
使用调试工具
Xdebug(最强大)
// php.ini 配置 [xdebug] xdebug.mode = debug xdebug.start_with_request = yes xdebug.log = /path/to/xdebug.log
使用 Chrome DevTools
// 在浏览器中查看网络请求
fetch('/api/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({key: 'value'})
})
.then(response => response.json())
.then(data => console.log(data));
记录请求日志
自定义日志系统
<?php
class ApiLogger {
private $logFile;
public function __construct($logFile = 'api_log.txt') {
$this->logFile = $logFile;
}
public function log($type, $message, $extra = []) {
$logEntry = [
'timestamp' => date('Y-m-d H:i:s'),
'type' => $type,
'message' => $message,
'uri' => $_SERVER['REQUEST_URI'] ?? 'CLI',
'method' => $_SERVER['REQUEST_METHOD'] ?? 'CLI',
'ip' => $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0',
'extra' => $extra
];
file_put_contents(
$this->logFile,
json_encode($logEntry, JSON_PRETTY_PRINT) . "\n",
FILE_APPEND
);
}
}
// 使用示例
$logger = new ApiLogger();
$logger->log('REQUEST', 'API调用', ['data' => $_POST]);
$logger->log('ERROR', '参数错误', ['field' => 'email']);
?>
使用开发中间件
Slim Framework 调试中间件
<?php
// 使用 Slim 框架
use Slim\Factory\AppFactory;
use Slim\Middleware\ErrorMiddleware;
$app = AppFactory::create();
// 添加错误处理中间件
$errorMiddleware = new ErrorMiddleware(
$app->getCallableResolver(),
$app->getResponseFactory(),
true, // 显示错误详情
true, // 记录错误
true // 详细日志
);
$app->add($errorMiddleware);
// 自定义日志中间件
$app->add(function ($request, $handler) {
$logger = new ApiLogger();
$logger->log('REQUEST', 'Incoming request', [
'uri' => $request->getUri()->__toString(),
'method' => $request->getMethod(),
'headers' => $request->getHeaders(),
'body' => $request->getBody()->__toString()
]);
$response = $handler->handle($request);
$logger->log('RESPONSE', 'Outgoing response', [
'status' => $response->getStatusCode(),
'headers' => $response->getHeaders(),
'body' => $response->getBody()->__toString()
]);
return $response;
});
?>
命令行调试工具
PHP 内置服务器 + Curl
# 启动PHP内置服务器
php -S localhost:8000 -t public
# 在另一个终端发送请求
curl -X POST http://localhost:8000/api/data \
-H "Content-Type: application/json" \
-d '{"key":"value"}' \
-v # -v 显示详细信息
# 使用 --trace 查看完整请求
curl -X GET http://localhost:8000/api/users \
--trace-ascii /dev/stdout
使用 Postman/Insomnia
这些工具可以方便地调试,支持:
- 环境变量
- 自动化测试
- 请求历史
- 集合管理
专业调试技巧
捕获异常并记录
<?php
set_exception_handler(function ($exception) {
$logger = new ApiLogger();
$logger->log('EXCEPTION', $exception->getMessage(), [
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'trace' => $exception->getTraceAsString()
]);
// 返回 JSON 错误
header('Content-Type: application/json');
echo json_encode([
'success' => false,
'error' => $exception->getMessage()
]);
});
?>
性能分析
<?php
// 测量请求时间
$start = microtime(true);
// 你的业务代码
// ...
$end = microtime(true);
$executionTime = $end - $start;
$logger->log('PERFORMANCE', '请求耗时', [
'time' => $executionTime . ' 秒',
'memory' => memory_get_peak_usage(true) / 1024 / 1024 . ' MB'
]);
?>
完整调试示例
<?php
class HttpDebugger {
private $logFile;
private $requestId;
public function __construct($logFile = 'http_debug.log') {
$this->logFile = $logFile;
$this->requestId = uniqid('req_', true);
}
public function capture() {
// 捕获请求信息
$request = [
'id' => $this->requestId,
'time' => date('Y-m-d H:i:s'),
'method' => $_SERVER['REQUEST_METHOD'],
'uri' => $_SERVER['REQUEST_URI'],
'ip' => $_SERVER['REMOTE_ADDR'],
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
'headers' => getallheaders(),
'get' => $_GET,
'post' => $_POST,
'cookies' => $_COOKIE,
'files' => $_FILES,
'raw_body' => file_get_contents('php://input')
];
$this->writeLog('REQUEST', $request);
}
public function executeAndLog(callable $callback) {
$start = microtime(true);
try {
$result = $callback();
$status = 'SUCCESS';
$data = $result;
} catch (Exception $e) {
$status = 'ERROR';
$data = [
'message' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
];
}
$response = [
'id' => $this->requestId,
'status' => $status,
'execution_time' => microtime(true) - $start,
'memory_usage' => memory_get_peak_usage(true),
'data' => $data
];
$this->writeLog('RESPONSE', $response);
return $result;
}
private function writeLog($type, $data) {
$log = [
'timestamp' => date('Y-m-d H:i:s'),
'type' => $type,
'request_id' => $this->requestId,
'data' => $data
];
file_put_contents(
$this->logFile,
json_encode($log, JSON_PRETTY_PRINT) . "\n\n",
FILE_APPEND
);
}
}
// 使用示例
$debugger = new HttpDebugger();
$debugger->capture();
// 执行业务逻辑
$debugger->executeAndLog(function() {
// 你的业务代码
return ['status' => 'ok'];
});
?>
最佳实践建议
-
开发环境:开启所有错误报告
error_reporting(E_ALL); ini_set('display_errors', '1'); -
生产环境:记录到日志而不是输出
error_reporting(E_ALL); ini_set('display_errors', '0'); ini_set('log_errors', '1'); -
使用环境变量区分模式
define('DEBUG_MODE', true); // 或 false
if (DEBUG_MODE) { // 调试代码 }
4. **保持日志文件大小限制**
```php
if (filesize($logFile) > 1048576) { // 1MB
rename($logFile, $logFile . '.old');
}
这些方法可以根据实际需求组合使用,选择最适合你项目的调试方案。