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

PHP 將純文字 URL 自動轉為可點擊連結(保留既有 /、支援多種協定、效能優化)

     編輯:PHP 相關知識

核心挑戰

文字中混雜:

  • 純網址:https://example.com → 需轉換
  • 既有連結:<a href="...">...</a> → 不可動
  • 圖片標籤:<img src="..."> → 不可動
  • 程式碼區塊、郵件地址、非標準埠號、IP 位址、路徑參數...

策略:佔位符法(三階段)

  1. 保護:用唯一佔位符替換所有 <a>、<img> 標籤,暫存原始標籤陣列。
  2. 轉換:對剩餘文字套用 URL 正則,替換為 <a> 標籤。
  3. 還原:依序將佔位符替換回原始標籤。

完整實作(支援 http/https/ftp/ftps、www、IP、埠號、路徑、查詢字串、片段)


function autoLinkUrls(string $text): string {
    // 階段 1:保護既有  和 
    $placeholders = [];
    $protected = $text;

    // 保護  標籤(含巢狀屬性、單雙引號)
    $protected = preg_replace_callback(
        '/]*href\s*=\s*["\'][^"\']*["\'][^>]*>.*?<\/a>/is',
        function ($m) use (&$placeholders) {
            $ph = '{{AUTO_LINK_PLACEHOLDER_A_' . count($placeholders) . '}}';
            $placeholders[$ph] = $m[0];
            return $ph;
        },
        $protected
    );

    // 保護  標籤
    $protected = preg_replace_callback(
        '/]*src\s*=\s*["\'][^"\']*["\'][^>]*>/i',
        function ($m) use (&$placeholders) {
            $ph = '{{AUTO_LINK_PLACEHOLDER_IMG_' . count($placeholders) . '}}';
            $placeholders[$ph] = $m[0];
            return $ph;
        },
        $protected
    );

    // 階段 2:轉換純文字 URL
    // 正則:協定可選、www 可選、IP 或域名、埠號、路徑、查詢、片段
    $urlRegex = '~
        (?:                              # 協定(可選)
            (?:https?|ftps?)://          # https:// https:// ftp:// ftps://
        |                                # 或
            www\.                        # www. 開頭
        )
        (?:                              # 主機
            (?:[a-z0-9-]+\.)+[a-z]{2,}   # 標準域名
        |                                # 或
            \d{1,3}(?:\.\d{1,3}){3}      # IPv4
        )
        (?::\d+)?                        # 選擇性埠號
        (?:/[^\s<>"\']*)?                # 選擇性路徑(不含空白、<、>、引號)
        (?:\?[^\s<>"\']*)?               # 選擇性查詢字串
        (?:#[^\s<>"\']*)?                # 選擇性片段
    ~ix';

    $linked = preg_replace_callback($urlRegex, function ($m) {
        $url = $m[0];
        // 確保有協定
        if (!preg_match('~^https?://|ftps?://~i', $url)) {
            $url = 'https://' . $url;
        }
        return '' . htmlspecialchars($url, ENT_QUOTES, 'UTF-8') . '';
    }, $protected);

    // 階段 3:還原佔位符
    foreach ($placeholders as $ph => $original) {
        $linked = str_replace($ph, $original, $linked);
    }

    return $linked;
}

// 測試
$text = '訪問 https://example.com 和 www.google.com,但保留 既有連結 和  圖片。';
echo autoLinkUrls($text);

正則細節說明

  • ~ix 修飾符:i 大小寫不敏感、x 忽略正則內空白與註解(可讀性)。
  • 協定部分:(?:https?|ftps?)://|www\. 涵蓋常見協定與無協定 www 開頭。
  • 主機部分:支援標準域名(含子域名、連字號)與 IPv4。
  • 排除字元:[^\s<>"\'] 避免吞噬 HTML 標籤屬性、引號、空白。
  • htmlspecialchars 防 XSS,rel="noopener noreferrer" 安全新分頁。

效能優化建議

  • 預編譯正則:靜態變數儲存 $urlRegex,避免重複編譯。
  • 長文字分塊處理:超過 100KB 文字建議分段處理,避免 PCRE 回溯爆炸。
  • 快取結果:相同內容(如文章內容)快取轉換後 HTML。
  • 替代方案:大型專案考慮 url-highlight 或 JS 端 autolinker.js 前端渲染,減輕後端壓力。

結語

「保護 → 轉換 → 還原」三階段佔位符法,能完美解決「不破壞既有標籤」的核心需求。搭配嚴謹的 URL 正則、XSS 防護、效能優化,即可在論壇、評論、CMS 內容中安全部署自動連結功能。

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