PHP如何过滤敏感词再写文件_PHP过滤敏感词写法【过滤】

3次阅读

str_replace更适合简单敏感词过滤,preg_replace适用于复杂匹配;需注意赋值、空值清理、编码与权限校验;词表应外置并配合redis或时间戳实现热更新。

PHP如何过滤敏感词再写文件_PHP过滤敏感词写法【过滤】

敏感词过滤用 str_replace 还是 preg_replace

直接替换简单词用 str_replace 更快、更安全;含通配、大小写混排或需模糊匹配(如“和-谐”“h3xie”)才考虑正则。但正则容易写错边界,比如没加 b 导致“和谐号”被误拦,或漏掉 Unicode 变体(如全角空格、零宽字符)。生产环境建议先用 str_replace + 精确词表,再按需补正则规则。

写文件前必须校验过滤是否生效

常见错误是调用 str_replace 后没接返回值,原字符串未变就直接写入:

$content = str_replace($badwords, $replace, $content); // ✅ 正确赋值
// ❌ 忘了这行:$content = ...,结果写的是原始内容

另一个坑是敏感词数组含空字符串或 NULL,导致 str_replace 报 Warning 并跳过过滤。建议过滤前加判断:

  • array_filter($badwords, 'strlen') 清理无效项
  • is_string($content) 确保输入类型正确
  • 写文件前 if ($content !== $original) 检查是否真有替换发生

写文件时注意权限与编码一致性

过滤后写文件失败,常因两件事:一是目标目录无写权限,二是敏感词含中文却用 file_put_contents 默认 ASCII 写入,造成乱码甚至截断。解决方法

  • 写前用 is_writable($path) 检查路径可写
  • 强制指定 UTF-8 编码:file_put_contents($file, mb_convert_encoding($content, 'UTF-8', 'auto'), LOCK_EX)
  • 避免直接拼接用户输入进文件名,否则可能路径穿越(如 ../../etc/passwd),应限定后缀并过滤路径分隔符

敏感词更新后如何不重启服务就生效?

硬编码词表改一次就得重部署,线上应把词表放独立文件(如 sensitive_words.php 返回数组),每次过滤前 require_once 加载。但注意 PHP opcode 缓存(如 OPcache)会缓存该文件,导致修改不生效。解决方案:

  • 开发期关 OPcache,或设 opcache.file_update_protection=0
  • 生产期用时间戳校验:if (filemtime($wordfile) > $cached_time) { require $wordfile; }
  • 更稳的方式是走 redis 缓存词表,用 GET sensitive:words 读取,更新时 SET 即刻生效

真正难的不是替换,是词表维护、编码穿透、缓存失效这三个点串起来出问题。

text=ZqhQzanResources