Laravel 10 中推荐使用注入的 $request 实例调用 $request->query() 获取 GET 参数,Input::get() 和 Request::query() 已软弃用;$request->query() 仅读取查询字符串,安全且类型明确,而 $request->input() 会合并多种来源,易导致误判。

request()->query 和 $request->query() 依然有效,但直接用 $_GET、Input::get() 或 Request::query()(静态调用)在 Laravel 10 中已不推荐——不是语法报错,而是被标记为“软弃用”,后续版本会彻底移除。
为什么 Input facade 和 Request::query() 不再安全
Laravel 10 彻底移除了 Illuminate\Support\Facades\Input facade,它早在 Laravel 5.2 就被标记为废弃,只是拖到 10 才真正删掉;而 Request::query() 这类静态调用依赖容器自动解析,但在某些上下文(如 Artisan 命令、队列任务、中间件早期阶段)中可能返回空或抛出 BindingResolutionException。
常见错误现象包括:
- 本地开发正常,部署到生产环境后
Input::get('page')返回null却无报错 - 单元测试里模拟请求时,
Request::query('sort')始终为空 - IDE 提示 “Method 'query' not found on static class”
正确获取 GET 参数的三种方式
优先使用注入的 $request 实例,它是类型安全、可 mock、且生命周期明确的方案。
- 控制器方法中:直接声明
Request $request参数,调用$request->query('key')或$request->query('key', 'default') - 闭包路由中:用
function (Request $request) { ... }显式注入 - 中间件中:已在
handle方法签名里接收$request,直接用$request->query('token')即可 - 全局辅助函数
request()仍可用,但仅限简单场景;它本质是app('request')的快捷方式,不保证在所有上下文中都已绑定
示例:
use Illuminate\Http\Request;
Route::get('/search', function (Request $request) {
$q = $request->query('q'); // ✅ 推荐
$page = $request->query('page', 1); // ✅ 带默认值
$filters = $request->query(); // ✅ 获取全部 GET 参数为数组
});
容易踩的坑:query() vs input() vs querystring 解析
$request->query() 只读取 URL 查询字符串(?a=1&b=2),不包含 POST body、JSON 或路由参数;而 $request->input() 是更宽泛的入口,会合并 query + post + request body(含 JSON),但代价是模糊了数据来源,在调试和安全校验时容易误判。
- 需要严格区分来源时(比如日志审计、白名单过滤),必须用
$request->query('x') - 不要用
$request->input('x')替代$request->query('x'),除非你明确要 fallback 到 POST - 如果 GET 参数含数组语法(如
?tags[]=php&tags[]=laravel),$request->query('tags')自动返回['php', 'laravel'],无需手动处理 - 中文或特殊字符参数(如
?name=张三&city=Shanghai%20%2F%20Beijing)会被自动解码,无需再调urldecode()
兼容旧代码的最小改动方案
如果你有大量遗留代码还在用 Input::get(),最稳妥的过渡方式是定义一个简短的全局函数(放在 app/Helpers/RequestHelper.php 并 autoload):
if (!function_exists('input_get')) {
function input_get($key = null, $default = null) {
return request()->query($key, $default);
}
}
然后全局搜索替换 Input::get( → input_get(。注意:这只是临时兜底,不能解决 IDE 支持和类型提示问题,长期仍应转向 Request 注入。
真正复杂的地方在于中间件早期阶段——比如在 TrustProxies 或自定义 CORS 中间件里,$request 对象虽已存在,但 query() 可能尚未解析(尤其当请求是 multipart/form-data 且未触发 full parse 时)。此时应确保中间件注册顺序靠后,或显式调用 $request->query() 前先触发解析逻辑(如 $request->all() 一次)。


















