必须用 $request->get() 获取 get 参数,而非 $_get;它自动处理 csrf、过滤、默认值、类型安全及特殊键名,避免注入、错误和语法问题。

直接用 $request->get(),别碰 $_GET —— 否则 CSRF、类型、默认值都得自己兜底。
GET 参数取值必须用 $request->get() 而不是 $_GET
Yii2 的请求对象做了多层封装:自动校验 CSRF(表单场景)、过滤危险字符、支持默认值、兼容 URL 中的数组写法(如 ?tags[]=a&tags[]=b)。绕过它直接读 $_GET,轻则拿不到值(被静默拦截),重则引发 SQL 注入或类型错误。
-
$_GET['id']在开启 CSRF 验证的表单提交中可能为空,而$request->get('id')会正常返回(CSRF 校验走的是请求头或隐藏字段,不影响 GET 参数读取) -
$request->get('page', 1)比isset($_GET['page']) ? (int)$_GET['page'] : 1更安全简洁,且避免 Notice 级错误 - 传了
?id=123,但数据库查询用了WHERE id = :id绑定,如果没转类型,$_GET['id']是字符串,某些驱动会报错;(int)$request->get('id')才是可控的
带连字符(-)或点号(.)的参数名不能当方法参数注入
比如 URL 是 /user/view?customer-id=1001,控制器动作 public function actionView($customer-id) 会直接语法报错 —— PHP 不允许变量名含 -。框架也不会自动把 customer-id 映射成 $customer_id。
- 必须显式调用
$request->get('customer-id')获取 - 同理,
api.version、user_email这类含点或下划线的键,也不能依赖自动注入,一律走get()方法 - 如果大量使用这类命名,建议在 Action 开头统一提取并重命名:
$customerId = $request->get('customer-id', 0);
$request->get() 和 $request->queryParams 的区别
二者返回内容一致,但语义和使用时机不同:$request->queryParams 是只读缓存数组,$request->get() 是带逻辑的方法调用(支持默认值、类型安全检查)。
- 需要默认值或单个字段时,无条件选
$request->get('key', 'default') - 要遍历全部 GET 参数(如日志记录、透传给下游服务),用
$request->queryParams更轻量,避免重复解析 - 不要混用:
$request->get()内部会从$request->queryParams取数,但加了空值判断和类型适配;直接改$request->queryParams数组不会影响后续get()行为(它是副本)
JSON 请求体里混着 GET 参数?别指望 get() 自动合并
GET 参数永远来自 URL 查询字符串,跟请求体(body)无关。哪怕你发的是 POST /api?foo=bar + JSON body,$request->get('foo') 仍能取到 bar,但 $request->post('xxx') 或 $request->getBodyParam('xxx') 才负责解析 body。
- 常见误判:前端用 fetch 发
GET请求却把参数塞进 body(非法),此时$request->get()拿不到任何东西 —— 浏览器根本不会发 body - 调试时先确认请求方法和 URL:用
$request->isGet判断,再看$request->url是否含查询串 - 如果 URL 没有
?,$request->get()返回空数组,不是 null,注意判空逻辑
最易被忽略的一点:GET 参数不参与 CSRF 校验,但如果你在 GET 请求里做敏感操作(如删除、状态切换),框架不会拦,得靠自己加权限控制或改用 POST —— $request->get() 再安全,也救不了设计漏洞。











