Yii2中参数过滤应通过模型rules()中的filter验证器实现,如['name', 'filter', 'filter' => 'trim'],而非直接使用PHP的filter_input;safe属性仅控制批量赋值,不提供过滤功能;防XSS需结合Html::encode()或HtmlPurifier扩展。

Yii2里怎么用filterInput做参数过滤
Yii2本身不提供叫filterInput的函数——这是PHP原生的filter_input,但直接在Yii2里混用容易绕过框架的安全机制。正确做法是走Yii2自己的验证和过滤流程,核心在rules()和safe、filter验证器。
常见错误:在Controller里用filter_input(INPUT_GET, 'id')取值后直接拼SQL或渲染,结果XSS或SQL注入照旧发生,因为没进模型校验层。
- 所有用户输入必须进
Model(哪怕只是FormModel),不能在Controller里裸调Yii::$app->request->get()后直接用 -
filter验证器只做类型转换和简单清洗,比如trim、intval,不防XSS;防XSS得靠htmlspecialchars输出时处理,或HtmlPurifier扩展 - 如果要保留HTML内容又想过滤危险标签,必须显式加
HtmlPurifier规则,不能只靠filter
在rules()里写filter验证器的实际写法
过滤不是“额外动作”,而是验证规则的一部分。比如把字符串首尾空格去掉、强制转整数、转小写,都该在rules()里声明,而不是在beforeValidate()里手动处理。
典型场景:搜索关键词要去空格、用户名要转小写、ID字段必须是整数。
-
['name', 'filter', 'filter' => 'trim']—— 注意是filter,不是trim(后者是验证器名,会报错) -
['id', 'filter', 'filter' => 'intval']—— 但要注意intval('1abc')返回1,不是严格类型校验,真要强校验得配integer验证器 -
['email', 'filter', 'filter' => 'strtolower']—— 配合email验证器用,避免大小写导致重复注册
示例:
public function rules()
{
return [
['username', 'filter', 'filter' => 'trim'],
['username', 'filter', 'filter' => 'strtolower'],
['username', 'string', 'min' => 3, 'max' => 20],
['id', 'filter', 'filter' => 'intval'],
['id', 'integer', 'min' => 1],
];
}
为什么safe属性不能代替过滤
safe只是允许批量赋值(massive assignment),它本身不做任何清洗或转换。很多人误以为标了safe就“安全”了,其实完全相反——它只是开了白名单,让字段能被load()接收,后续仍需靠filter或validate来处理。
错误现象:表单提交<script>alert(1)</script>到content字段,模型里只写了['content', 'safe'],结果存库/渲染时原样输出,XSS立刻触发。
-
safe≠ 过滤,也不等于转义,它只是“允许这个字段被load()进来” - 真正需要过滤的字段,必须显式加
filter规则;需要防XSS的,还得在视图里用Html::encode()或配置View::defaultExtension - 敏感字段如
html_content,建议默认不safe,改用scenarios()控制不同场景下的可赋值字段
第三方扩展HtmlPurifier怎么接入才不踩坑
Yii2自带的filter对HTML无能为力。HtmlPurifier是事实标准,但直接在rules()里配容易出问题:配置错位置、没装扩展、过滤后丢失换行等。
使用场景:富文本编辑器提交的内容、后台公告、用户评论。
- 先执行
composer require ezyang/htmlpurifier,别漏掉autoload - 过滤规则必须写在
filter验证器里,且filter参数要传回调:['content', 'filter', 'filter' => function ($value) { return \HtmlPurifier::process($value); }] - 默认配置会删掉
style和script,但也会删掉br、p,需自定义HTML.Allowed或CSS.AllowedProperties - 性能敏感场景慎用——每次请求都解析HTML,建议配合缓存,或前端提交前先做轻量清洗
事情说清了就结束。


















