首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 敏感詞過濾實戰:基於 strpos 的關鍵字檢測與陷阱排查

     編輯:PHP 綜合知識

需求背景

網站內容多為用戶生成(UGC),為符合法規需預先過濾敏感關鍵字。本文示範使用 strpos() 實現關鍵字檢測,並詳述從檔案讀取關鍵字時遇到的「隱形空白字元」陷阱及解決方案。

核心思路

  1. 將關鍵字存於文字檔(每行一個)
  2. PHP 讀取檔案並轉為陣列
  3. 遍歷陣列,逐一用 strpos() 檢測內容是否包含關鍵字

初版程式碼(含 Bug)

<?php
function keyWordCheck($content) {
    $content = trim($content);
    // 讀取關鍵字檔案
    $kw_content = @file_get_contents('keyWords.txt');
    $arr = explode("\n", $kw_content);

    for ($i = 0, $k = count($arr); $i < $k; $i++) {
        if ($arr[$i] === '') continue; // 跳過空行
        // 直接檢測,未處理換行符/空白
        if (strpos($content, $arr[$i]) !== false) {
            return $arr[$i]; // 回傳命中的關鍵字
        }
    }
    return false;
}
?>

Bug 現象與排查過程

  • 現象:明明內容包含關鍵字,檢測卻總回傳「通過」
  • 排查:
    • 編碼問題?將檔案存為 UTF-8 → 無效
    • 檔案讀取失敗?print_r() 顯示陣列正常 → 非讀取問題
    • 將關鍵字直接寫死在程式陣列中 → 檢測正常!

真相:隱形空白字元

從文字檔 explode("\n") 產生的陣列元素,往往殘留 \r(Windows 換行符)或前後空白。導致 strpos($content, "關鍵字\r") 永遠不匹配。

修正版:加上 trim() 淨化每個關鍵字

<?php
function keyWordCheck($content) {
    $content = trim($content);
    $kw_content = @file_get_contents('keyWords.txt');
    $arr = explode("\n", $kw_content);

    for ($i = 0, $k = count($arr); $i < $k; $i++) {
        if ($arr[$i] === '') continue;
        // 關鍵修正:trim() 移除首尾空白與換行符
        $keyword = trim($arr[$i]);
        if (strpos($content, $keyword) !== false) {
            return $keyword;
        }
    }
    return false;
}

// 使用範例
$content = '這裡是要發布的內容,含有關鍵字2';
$kw = keyWordCheck($content);
if ($kw) {
    echo '偵測到敏感詞:【' . $kw . '】';
} else {
    echo '恭喜!通過關鍵字檢測';
}
?>

效能與擴展建議

  • 關鍵字量大時,建議改用 Trie 樹(字典樹) 或 Aho-Corasick 自動機 算法,單次掃描即可匹配所有關鍵字,時間複雜度 O(n)。
  • 生產環境應將關鍵字快取於記憶體(Redis / APCu),避免每次請求讀取檔案。
  • 需支援多語言、模糊匹配(如同音字、變體字)時,可引入分詞庫(如 jieba-php)配合正則擴展。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved