hyperf 3.0 中 $request->query() 返回 null 并非框架 bug,而是请求的 query string 在 nginx/apache/iis 等反向代理环节被截断或未透传所致;常见原因包括 nginx proxy_pass 未拼接 $args 或 $request_uri、apache .htaccess 缺失 [qsa] 标志、iis arr 错用重定向而非重写。

Hyperf 3.0 中 Request 对象读不到 Query 参数(比如 $request->query('page') 返回 null),不是框架 Bug,而是请求根本没把查询字符串传进来——通常卡在 URL 重写或反向代理环节。
为什么 $request->query() 总是空?
Hyperf 的 Request 对象基于 PSR-7 实现,query 方法解析的是原始请求 URI 中的 query string(即 ?a=1&b=2 部分)。如果这一段在到达 Hyperf 前就被截断、丢弃或未正确透传,就必然为空。
- 常见于 Nginx/Apache 反向代理配置中漏了
$args或query_string透传 - IIS ARR 规则里用了“重定向”而非“重写”,导致浏览器跳转后 query string 被浏览器二次编码或截断
- Apache
.htaccess中RewriteRule缺少[QSA]标志,原始参数被丢弃 - 前端发请求时 URL 已被 JS 拼错(如
?a=1&b=2多余转义)
Nginx 反向代理必须透传 $args
如果你用 Nginx 做前置代理,确保 proxy_pass 后带 $args,否则 query string 会丢失:
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
location /api/ {
proxy_pass http://127.0.0.1:9501/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# 关键:必须显式拼接 $args
proxy_pass_request_headers on;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
- 错误写法:
proxy_pass http://127.0.0.1:9501;(结尾无/+ 无$args,会导致 query string 丢失) - 更稳妥写法:用
proxy_pass http://127.0.0.1:9501$request_uri;,直接透传完整 URI - 注意:Nginx 默认不会修改或过滤 query string,但若启用了
rewrite规则又没加[QSA],也会丢参
Apache .htaccess 里漏掉 [QSA] 是高频坑
子目录路由(如 /items/)下用 .htaccess 转发到 index.php 时,必须加 [QSA]:
RewriteEngine On
RewriteBase /items/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L,QSA]
- 没有
[QSA]:访问/items/list?page=2→$_SERVER['QUERY_STRING']为空 →$request->query('page')为null - 有
[QSA]:Apache 自动把原始page=2追加到转发后的 URI query string 中 - 别用
[R](重定向)代替[L](内部重写),否则变成浏览器跳转,协程上下文也会中断
IIS ARR 规则中“操作类型”选错导致 query string 丢失
IIS 的 URL 重写模块里,“操作类型”必须选 重写(Rewrite),不能选 重定向(Redirect):
- 重定向(301/302):浏览器收到跳转响应后重新发起请求,原始 query string 可能被浏览器处理异常(尤其含特殊字符时)
- 重写(Rewrite):IIS 内部转发,保持原始请求方法、headers 和 query string 完整透传
- 检查规则中的“重写 URL”字段是否包含
{R:1}且末尾不带问号(如http://localhost:4000/{R:1}✅;http://localhost:4000/{R:1}?❌) - ARR 默认启用“保留客户端 IP”,但 query string 不在此列,需靠规则本身保障
真正难排查的点在于:问题现象(query 为空)和根因(代理层丢参)之间隔着一层抽象,你看到的是 Request 对象没数据,但实际它从来就没收到过。动手前先用 curl -v "http://your-domain/api/test?x=1" 直连 Hyperf 端口验证,再逐层往前查代理配置。










