ThinkPHP 8.0 中用责任链模式实现敏感词过滤,通过统一接口定义处理器,按序执行检测→替换→拦截,各处理器专注一类规则(如黑名单、正则、表情),中间件中组装链并处理请求体复用问题。

在 ThinkPHP 8.0 中,用责任链模式过滤请求参数里的敏感词(比如脏话),核心是把“检测→替换→拦截”这些动作拆成独立、可插拔的处理器,按需串联执行。不硬编码 if-else,也不依赖单一过滤器,而是让每个规则各司其职、顺序可控、增删自由。
定义统一的敏感词处理器接口
先抽象一个标准处理契约,所有脏话过滤逻辑都实现它:
- 接口方法返回 bool:true 表示已处理(可继续传递),false 表示终止链(如命中违禁词直接拦截)
- 接收 think\Request 对象和原始参数数组,允许读取、修改、中断
- 避免直接操作全局 $_GET/$_POST,用 TP 封装的 Request 更安全
编写具体脏话处理器(示例)
每个类只专注一类词,比如:
- BlacklistFilter:匹配黑名单库(如“傻逼”“操”),命中则设 $request->deny() 并返回 false
- RegexFilter:用正则识别变体(如“s*b”“cào”),替换为 * 号并继续链
- EmojiFilter:过滤含恶意表情组合(如“?+❌”暗示攻击),仅记录不阻断
组装责任链并注入中间件
在 app/middleware/ 下新建 SensitiveWordChain.php:
- 构造函数中按优先级 new 多个处理器,存入数组(顺序即执行顺序)
-
handle()方法遍历数组,调用每个process($request, $params) - 任一处理器返回 false,立即
return response()->fail('含违规内容') - 注册到全局中间件或路由组,确保所有需过滤的接口都经过它
注意请求体复用问题(尤其 POST/JSON)
TP8 的 Request 默认只解析一次 body,若多个处理器都调 $request->post() 可能拿空值:
- 首次调用后,缓存原始 rawInput 或 parsed data 到属性(如
$this->rawParams) - 后续处理器直接读缓存,避免重复解析流(InputStream 不可重置)
- 对 JSON 请求,提前
json_decode($request->getContent(), true)并共享结果


















