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

PHP 文章關鍵字自動加超連結實作:陣列映射與 str_replace 技巧

     編輯:PHP 綜合知識

需求場景

內容管理系統、部落格、論壇常需將文章中的特定關鍵字 (如「SEO」、「PHP」、「JavaScript」) 自動轉為指定 URL 的超連結,提升站內導流與 SEO 權重傳遞。

基礎實作:關鍵字陣列 + 迴圈替換

<?php
$keywords = [
    ['網頁特效', '/js_a/js.html'],
    ['seo', '/seo/seo.html'],
    ['php', '/phper/php.html'],
    ['jsp', '/jsp/jsp.html'],
    ['asp', '/asp/asp.html'],
    ['ps', '/fw/photo.html'],
    ['photoshop', '/fw/photo.html'],
    ['javascript', '/js_a/js.html'],
    ['.net', '/net/net.html'],
    ['非主流', '/fw/photo.html'],
    ['網絡', '/mon/mon.html'],
    ['css', '/cssdiv/css.html'],
    ['平面設計', '/fw/photo.html'],
    ['網站', '/person/'],
    ['網頁制作', '/wy/yw.html'],
    ['搜索引擎', '/seo/seo.html'],
    ['優化', '/seo/seo.html'],
    ['動畫', '/flash_a/flash.html'],
    ['數據庫', '/database/database.html'],
    ['掙錢', '/mon/mon.html'],
    ['運營', '/mon/mon.html'],
];

$str = "今天是2010年5月30號,我的網站出現的問題這對seo有很多的問題,seo就是搜索引擎優化了,以前學php好啊現在覺得jsp好,css+div,網頁,網頁設計,網頁制作,網頁學習,網頁教學,Photoshop,Flash,HTML,CSS,Dreamweaver,Fireworks,ASP,PHP,JSP,ASP.NET,網站建設,網站開發,網頁特效,平面設計,個人網站,網頁素材";

echo "原始內容:$str<br><br>";

foreach ($keywords as $pair) {
    $kw = $pair[0];
    $url = $pair[1];
    if (strpos($str, $kw) !== false) {
        $str = str_replace($kw, '' . $kw . '', $str);
    }
}

echo "處理後內容:$str";
?>

進階問題與優化方案

1. 重複替換與巢狀標籤問題

若關鍵字有包含關係 (如 `php` 和 `php framework`),短關鍵字先替換會破壞長關鍵字;且替換後的 `` 標籤內容若再被匹配,會產生巢狀 `` 導致 HTML 失效。

解決:按關鍵字長度降序排序,且僅在純文字節點替換 (需 DOM 解析)。

2. 大小寫不敏感替換

$str = preg_replace('/' . preg_quote($kw, '/') . '/i', '$0', $str);

3. 避免替換標籤屬性內容

純 `str_replace` 會誤替換 `href`、`alt`、`title` 等屬性值。正確做法:使用 `DOMDocument` 遍歷文字節點 (`TEXT_NODE`) 進行替換。

4. 效能優化:單次正則替換所有關鍵字

<?php
// 建立關鍵字 -> URL 映射
$map = [
    'seo' => '/seo/seo.html',
    'php' => '/phper/php.html',
    // ...
];

// 按長度降序排序,優先匹配長關鍵字
uksort($map, function($a, $b) { return strlen($b) - strlen($a); });

// 組合單一正則:(seo|php|javascript|...)
$pattern = '/(' . implode('|', array_map('preg_quote', array_keys($map), array_fill(0, count($map), '/'))) . ')/i';

$content = preg_replace_callback($pattern, function($m) use ($map) {
    $kw = $m[0];
    // 找到映射 (不分大小寫)
    $url = '';
    foreach ($map as $k => $v) {
        if (strcasecmp($k, $kw) === 0) { $url = $v; break; }
    }
    return $url ? '' . $kw . '' : $kw;
}, $content);
?>

生產級建議:使用 HTML 解析器

<?php
function autoLinkKeywords($html, array $keywordMap) {
    $dom = new DOMDocument();
    @$dom->loadHTML('' . $html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
    $xpath = new DOMXPath($dom);

    // 只選取文字節點,排除 script/style/textarea/a 內部
    $textNodes = $xpath->query('//text()[not(parent::script) and not(parent::style) and not(parent::textarea) and not(parent::a)]');

    // 按長度降序
    uksort($keywordMap, fn($a, $b) => strlen($b) - strlen($a));
    $pattern = '/(' . implode('|', array_map('preg_quote', array_keys($keywordMap), array_fill(0, count($keywordMap), '/'))) . ')/i';

    foreach ($textNodes as $textNode) {
        $newHtml = preg_replace_callback($pattern, function($m) use ($keywordMap) {
            $kw = $m[0];
            foreach ($keywordMap as $k => $v) {
                if (strcasecmp($k, $kw) === 0) return '' . $kw . '';
            }
            return $kw;
        }, $textNode->nodeValue);

        if ($newHtml !== $textNode->nodeValue) {
            $fragment = $dom->createDocumentFragment();
            $fragment->appendXML($newHtml);
            $textNode->parentNode->replaceChild($fragment, $textNode);
        }
    }

    return $dom->saveHTML();
}
?>

總結對照表

方案優點缺點適用場景
str_replace 迴圈簡單易懂大小寫敏感、破壞 HTML 結構、巢狀標籤、效能差純文字、簡單測試
preg_replace_callback 單一正則效能較好、支援大小寫、長度優先仍可能破壞屬性/標籤簡單 HTML、無巢狀風險
DOMDocument + XPath精準替換文字節點、保護 HTML 結構記憶體佔用大、速度較慢、需處理編碼生產環境、複雜 HTML、安全要求高

結語

關鍵字自動連結看似簡單,實則涉及 HTML 解析、替換順序、編碼、效能等多重考量。簡易專案可用正則優化版;正式產品強烈建議使用 `DOMDocument` 方案,確保輸出 HTML 結構完整、安全。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved