应优先使用 $request->query('key') 严格获取 url 查询参数,因 request()->input('key') 会优先检查 post/put 数据,在纯 get 请求中可能返回 null;控制器注入 $request 更规范,全局 request() 辅助函数适用于闭包或 blade。

如何在 Laravel 9 中正确获取 GET 参数
直接用 request()->query('key') 或 request('key') 即可,但必须清楚它们的默认行为和边界情况——Laravel 9 默认启用严格模式,request('key') 不会自动 fallback 到 query,它优先取 POST/PUT 数据,容易漏掉纯 GET 请求的值。
request() 和 $request 对象的区别与选择
控制器方法中注入 $request 是更明确、更易测试的方式;而全局 request() 辅助函数在闭包路由或 Blade 中更方便。两者底层都走 Illuminate\Http\Request,但行为一致的前提是:你没手动调用过 $request->replace() 或修改过请求实例。
-
request('name'):等价于request()->input('name'),会依次检查 POST、GET、route 参数,**不是只读 GET** -
request()->query('name'):**严格只读 URL 查询参数(即 ?name=xxx)**,推荐用于纯 GET 场景 -
$request->query('name', 'default'):支持默认值,且不触发任何输入过滤逻辑(比如 trim、cast)
常见错误:用 input() 代替 query() 导致参数丢失
典型现象:访问 /search?keyword=php,在控制器里写 request()->input('keyword') 返回 null。原因是你启用了 CSRF 保护(默认开启),而 GET 请求不带 _token 字段,Laravel 在某些配置下会拒绝解析 input 数据源。这不是 bug,是设计使然。
- GET 请求无 body,
input()依赖 Symfony 的getInputSource(),可能因 content-type 或中间件提前终止解析 -
query()直接读取$_GET副本,绕过所有解析链,最稳定 - 如果需要类型转换(如整型),用
request()->integer('page', 1),但它仍基于input(),所以对纯 GET 推荐先query()再 cast
验证场景下如何安全提取 GET 参数
用 validate() 方法时,默认校验的是 input() 数据,所以 ?sort=created_at&order=desc 这类分页参数必须显式允许——否则会被过滤掉。
- 写法:
$validated = $request->validate(['sort' => 'nullable|string|in:created_at,name', 'order' => 'nullable|string|in:asc,desc']) - 但注意:这个 validate 会尝试从所有来源取值,若你同时提交了同名 POST 字段,它会覆盖 GET 值
- 更稳妥的做法是先提取:
$params = $request->only(['sort', 'order']); $validated = Validator::make($params, [...])->validate();
GET 参数看似简单,但混用 input() 和 query()、忽略验证源、以及中间件对请求生命周期的干预,是 Laravel 9 里最容易踩空的三个点。











