请求 ID
OxPHP 处理的每个请求都会获得一个唯一标识符,用于追踪和日志关联。该 ID 会出现在响应头和访问日志中,因此你只需一个值就能在技术栈的每一层追踪同一个请求。
工作原理
OxPHP 会在其他一切逻辑运行之前,先为每个进入的请求分配一个 ID。如果客户端已经发送了 X-Request-ID 头(比如来自负载均衡器或 API 网关),OxPHP 会校验该值并沿用它。要通过校验,请求头长度必须为 1–64 个字符,且只能包含字母数字、连字符(-)、下划线(_)或点号(.)。任何未通过校验的值都会被替换为一个新生成的 ID。
当没有收到有效的 X-Request-ID 时,OxPHP 会生成一个 20 个字符的小写十六进制 ID,例如 67890abc12341a2b0042。该值编码了一个时间戳、一个进程唯一值和一个单调递增计数器,因此跨容器和跨重启发生冲突的可能性极低。
从此之后,这个 ID 便会随请求一路传递:
- 它会随每个响应通过
X-Request-ID响应头发出。 - 启用访问日志后,它会出现在每条访问日志记录的
request_id字段中。 - PHP 脚本可以通过
oxphp_request_id()读取它。
响应头
OxPHP 的每个 HTTP 响应都包含 X-Request-ID 头:
HTTP/1.1 200 OK
X-Request-ID: 67890abc12341a2b0042
Content-Type: text/html; charset=utf-8当上游负载均衡器或网关在进入的请求上提供了 X-Request-ID 时,OxPHP 会在响应中原样回传相同的值,从而在你的整个基础设施中实现端到端的可追踪性。
在 PHP 中读取请求 ID
使用 oxphp_request_id() 读取当前的请求 ID:
<?php
$requestId = oxphp_request_id();
// Include in application logs for correlation
$logger->info('Processing order', [
'request_id' => $requestId,
'order_id' => $orderId,
]);将请求 ID 转发给下游服务,以在各个 API 调用之间保持可追踪性:
<?php
$requestId = oxphp_request_id();
$ch = curl_init('https://api.example.com/users');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"X-Request-ID: $requestId",
]);
$response = curl_exec($ch);
curl_close($ch);访问日志记录
启用访问日志后,每条日志记录都包含 request_id 字段:
{
"timestamp": "2026-02-11T12:34:56.789Z",
"level": "INFO",
"fields": {
"request_id": "67890abc12341a2b0042",
"method": "GET",
"path": "/api/users",
"status": 200,
"duration_us": 1234,
"remote_ip": "10.0.0.1",
"message": "request completed"
}
}在你的日志聚合工具中按 request_id 过滤,即可追踪单个请求的完整生命周期,包括任何引用了同一 ID 的 PHP 错误或应用日志记录。
故障排查
响应中缺少 `X-Request-ID` 头
这是意料之外的情况。OxPHP 会为每个响应都添加该头,因此如果它缺失了,很可能是某个中间代理把它剥离了。
检查方法: 在路径中不经过任何代理的情况下,直接对 OxPHP 进行测试:
curl -v http://localhost:8080/ 2>&1 | grep -i x-request-id上游的 ID 没有被保留
进入的 X-Request-ID 值可能未通过校验。OxPHP 会拒绝为空、长度超过 64 个字符,或包含字母数字、连字符、下划线、点号以外字符的 ID。
检查方法: 检查上游发送的值,确认它满足字符和长度要求。常见的失败原因包括值中含有斜杠、空格或花括号字符。
`oxphp_request_id()` 返回空字符串
该函数仅在 OxPHP 中可用。如果你在 PHP-FPM 或 CLI 下运行相同的 PHP 代码,这个函数是未定义的。请用兼容性检查来保护对它的调用:
<?php
$requestId = function_exists('oxphp_request_id')
? oxphp_request_id()
: ($_SERVER['HTTP_X_REQUEST_ID'] ?? uniqid('', true));