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

PHP 文章關鍵字自動加超連結函數:支援巢狀關鍵字、可控替換次數、效能優化

     編輯:PHP 綜合知識

內容管理系統常見需求:文章發布時自動將預設關鍵字轉為超連結(如關鍵字「SEO」連結至 `/seo-guide`)。本文提供一個健壯的 keylink() 函數,解決關鍵字包含關係(如「PHP」與「PHP 7」)、替換次數控制、HTML 標籤保護等實務難題。

完整函數程式碼

<?php
/**
 * 文章關鍵字自動加連結
 *
 * @param string $str      原始文章內容
 * @param array  $linkDefs 關鍵字定義陣列,格式:['關鍵字,網址', ...]
 * @param int    $count    每個關鍵字最大替換次數(預設 1,0 表不限制)
 * @return string 處理後的 HTML 內容
 */
function keylink(string $str, array $linkDefs, int $count = 1): string
{
    // 1. 解析定義陣列為 [關鍵字 => 網址]
    $linkMap = [];
    foreach ($linkDefs as $row) {
        $parts = explode(',', $row, 2);
        if (count($parts) === 2) {
            $linkMap[trim($parts[0])] = trim($parts[1]);
        }
    }

    // 2. 先移除已存在的  標籤內同關鍵字,避免巢狀連結
    foreach ($linkMap as $kwd => $url) {
        $pattern = '/(<a.*?>\s*)' . preg_quote($kwd, '/') . '(\s*<\/a>)/sui';
        $str = preg_replace($pattern, '${2}', $str);
    }

    // 3. 依關鍵字長度由長到短排序,優先處理長關鍵字(如「PHP 7」先於「PHP」)
    uksort($linkMap, function ($a, $b) {
        return strlen($b) - strlen($a);
    });

    // 4. 處理關鍵字包含關係:暫時替換子關鍵字為唯一佔位符
    $placeholders = [];
    $keywords = array_keys($linkMap);
    foreach ($keywords as $i => $kwd) {
        for ($j = $i + 1; $j < count($keywords); $j++) {
            $subKwd = $keywords[$j];
            if (strpos($kwd, $subKwd) !== false) {
                $ph = '{' . md5($subKwd) . '}';
                $kwd = str_replace($subKwd, $ph, $kwd);
                $placeholders[$ph] = $subKwd;
            }
        }
        // 5. 實際替換為超連結
        $str = preg_replace(
            '/' . preg_quote($kwd, '/') . '/sui',
            '<a href="' . htmlspecialchars($linkMap[$kwd], ENT_QUOTES) . '" target="_blank">' . $kwd . '</a>',
            $str,
            $count
        );
    }

    // 6. 還原佔位符
    foreach ($placeholders as $ph => $orig) {
        $str = str_replace($ph, $orig, $str);
    }

    return $str;
}

// 使用範例
$links = [
    '百度,https://www.baidu.com/',
    '伺服器軟體,https://s.jb51.net/',
    'PHP,https://www.php.net/',
    'PHP 7,https://www.php.net/releases/7_0_0.php',
];

$article = '在百度搜尋 PHP 7 教學,也可查詢伺服器軟體相關資訊。';
echo keylink($article, $links, 1);
// 輸出:在<a href="https://www.baidu.com/" target="_blank">百度</a>搜尋 <a href="https://www.php.net/releases/7_0_0.php" target="_blank">PHP 7</a> 教學,也可查詢<a href="https://s.jb51.net/" target="_blank">伺服器軟體</a>相關資訊。
?>

核心邏輯詳解

  1. 長度排序:uksort 依關鍵字長度遞減,確保「PHP 7」優先於「PHP」被替換,避免變成 `PHP 7`。
  2. 巢狀關鍵字保護:偵測長關鍵字是否包含短關鍵字,暫時用 MD5 佔位符替換,替換完成後再還原。
  3. 既有連結保護:先移除 `關鍵字` 中的關鍵字,防止產生 `關鍵字` 巢狀連結。
  4. 可控替換次數:$count 參數直接傳給 preg_replace,預設只替換第一次出現,避免關鍵字堆砌影響閱讀體驗。
  5. 安全輸出:網址經 htmlspecialchars 處理,防止 XSS。

效能優化建議

  • 關鍵字數量大(>500):改用 preg_replace_callback_array 單次遍歷,或建立 Trie 樹/AC 自動機進行多模式匹配(可參考 php-aho-corasick 擴展)。
  • 文章極長:分段處理或使用 mb_strpos 定位後局部替換,避免單次正則處理超大字串導致記憶體飆升。
  • 快取編譯結果:關鍵字庫較固定時,將排序後的 $linkMap 序列化快取,避免每次請求重複解析排序。

常見陷阱與修正

擴充應用:關鍵字庫資料庫化

// 從資料庫讀取關鍵字庫
$stmt = $pdo->query("SELECT keyword, url FROM seo_keywords WHERE status=1 ORDER BY LENGTH(keyword) DESC");
$linkDefs = $stmt->fetchAll(PDO::FETCH_COLUMN | PDO::FETCH_GROUP); // 需調整格式
// 或手動組裝
$linkDefs = [];
while ($row = $stmt->fetch()) {
    $linkDefs[] = $row['keyword'] . ',' . $row['url'];
}
$content = keylink($content, $linkDefs, 2); // 每關鍵字最多替換 2 次

總結

本函數解決了關鍵字自動連結的核心痛點:巢狀關鍵字優先權、既有連結保護、替換次數控制、XSS 防護。實務上可搭配資料庫關鍵字庫、快取機制、佇列非同步處理,構建完整的 SEO 內連自動化系統。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
問題原因修正
關鍵字包含 HTML 標籤字元(如 `<` `>`)正則未轉義使用 preg_quote($kwd, '/') 轉義特殊字元
中文關鍵字匹配失效未加 u 修飾符正則加 /sui:s=單行模式、u=UTF-8、i=不區分大小寫
替換後連結指向錯誤佔位符還原順序錯誤確保長關鍵字先處理,佔位符用 MD5 確保唯一