ThinkPHP中应通过I函数、动态方法、DEFAULT_FILTER常量、中间件或工具函数对请求参数过滤以防范XSS和SQL注入;3.x用I函数和_default_filter,6.x须用中间件mergeParam清洗Request对象。

如果您在ThinkPHP应用中直接使用$_GET、$_POST等超全局变量,或未对input()、param()获取的数据做处理,则可能引入XSS、SQL注入等安全风险。以下是设置请求变量过滤的具体操作步骤:
一、使用I函数统一获取并过滤变量
I函数是ThinkPHP早期版本(3.x)提供的统一变量获取与过滤入口,支持在获取时即时调用过滤方法,避免原始数据裸露。该方式适用于快速加固旧项目,且无需修改路由或中间件结构。
1、在控制器或模型中调用I函数,指定变量类型、名称及过滤方法,例如:I('get.content', '', 'htmlspecialchars')。
2、对整组参数批量过滤,使用I('get.', [], 'htmlspecialchars')获取并清洗全部GET参数。
立即学习“PHP免费学习笔记(深入)”;
3、若需自定义过滤逻辑,可传入匿名函数:I('post.title', '', function($v) { return trim(strip_tags($v)); })。
4、注意:I函数默认启用DEFAULT_FILTER配置(通常为htmlspecialchars),但仅当未显式传入第三个参数时生效;一旦指定过滤方法,将覆盖默认行为。
二、在控制器中通过动态方法过滤
ThinkPHP 3.x的Action类提供_get、_post等动态方法,内置默认过滤机制,并允许按字段指定过滤器,适合细粒度控制单个请求动作的安全处理。
1、在控制器方法内调用$this->_get('username', 'htmlspecialchars', ''),获取并转义GET参数。
2、使用$this->_post('bio', 'htmlspecialchars|strip_tags')串联多个过滤函数,顺序执行。
3、若需跳过默认过滤,传入空字符串作为第二个参数:$this->_get('raw_html', '')。
4、所有动态方法均支持第三个参数设置默认值,如$this->_post('age', 'intval', 0)确保数值安全。
三、配置全局DEFAULT_FILTER常量
通过定义DEFAULT_FILTER常量,可为所有未显式指定过滤器的I函数及动态方法调用设定统一基础防护,属于低成本、高覆盖的基础安全策略。
1、在应用入口文件(如index.php)或配置文件中添加:define('DEFAULT_FILTER', 'htmlspecialchars');。
2、确认框架版本兼容性:该常量仅在ThinkPHP 3.x中生效,ThinkPHP 6.x不识别此定义。
3、若需组合过滤,可使用管道符分隔:define('DEFAULT_FILTER', 'htmlspecialchars|trim');。
4、注意:此配置不影响已显式传入过滤方法的调用,优先级低于手动指定的过滤器。
四、使用中间件对Request参数进行预清洗
在ThinkPHP 6.x中,中间件是拦截并重写请求参数的唯一可靠位置,必须通过mergeParam()将清洗后数据注入Request对象,否则input()、param()仍将返回原始值。
1、创建中间件类,例如app/middleware/XssFilter.php,实现handle方法。
2、在handle中调用$request->get()和$request->post()获取原始GET/POST数组。
3、对每个字符串值执行htmlspecialchars(strip_tags($value)),保留键名结构,跳过非字符串类型字段。
4、合并清洗结果:$request->mergeParam(array_merge($cleanedGet, $cleanedPost))。
5、在app/middleware.php中注册该中间件,确保其位于路由中间件之前。
五、封装通用参数清洗工具函数
针对高频使用的清洗场景(如富文本、普通表单、API参数),可封装独立工具函数,在控制器中按需调用,兼顾安全性与灵活性。
1、在app/common.php中定义函数:function clean_input($data, $rules = []) { ... }。
2、支持字段级规则映射,例如:clean_input($request->param(), ['title' => 'trim', 'content' => 'htmlspecialchars'])。
3、对嵌套数组递归处理,检测is_string后才执行htmlspecialchars,避免破坏JSON或ID类数值字段。
4、返回清洗后数组,直接用于验证器校验或模型赋值:$validated = (new UserValidate())->check($cleaned);。



















