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

PHP 檢測字串中是否包含外部連結

     編輯:PHP 綜合知識

內容審核、評論過濾常需判斷用戶輸入是否包含外站連結。本文提供 all_external_link() 函數,提取字串中所有 HTTP(S) 連結的域名,與當前域名 ($_SERVER['HTTP_HOST']) 比對,若存在不同域名則視為有外鏈。

函數代碼

function all_external_link($text = '', $host = '') {
    if (!$host) $host = $_SERVER['HTTP_HOST'];
    // 匹配 http(s)://domain 部分
    $pattern = '/https?:\/\/((?:[A-Za-z0-9-]+\.)+[A-Za-z]{2,})/i';
    if (!preg_match_all($pattern, $text, $matches)) {
        return true; // 無連結視為無外鏈
    }
    foreach ($matches[1] as $domain) {
        // 允許子域名 (如 api.example.com vs example.com)
        if (strcasecmp($domain, $host) !== 0 && !endsWith($domain, '.' . $host)) {
            return false; // 發現外鏈
        }
    }
    return true;
}

// 輔助函數
function endsWith($haystack, $needle) {
    return $needle === '' || substr($haystack, -strlen($needle)) === $needle;
}

// 測試
$text = '歡迎訪問 https://example.com 和 https://evil.com';
var_dump(all_external_link($text, 'example.com')); // false (含 evil.com)
var_dump(all_external_link($text, 'evil.com'));    // false (含 example.com)
var_dump(all_external_link('只有 https://api.example.com', 'example.com')); // true (子域名允許)

進階需求擴充

  • 白名單域名:增加 $whitelist 參數,允許特定合作夥伴域名。
  • 排除特定路徑:如允許 example.com/share/... 但阻擋 example.com/phishing。
  • 短網址展開:對 t.cn、bit.ly 等短網址發 HEAD 請求獲取真實域名 (需非同步/快取)。
  • 效能優化:大量文本改用 preg_match_all 一次性提取,避免循環正則。

誤判風險提醒

  • 正則無法完美解析所有合法 URL (IPv6、國際化域名、非標準埠口等)。
  • 用戶輸入 example.com (無協定) 不會被檢測,可視需求補充匹配裸域名。
  • Referer/Origin 標頭偽造風險同樣存在,關鍵業務需簽名 URL 或 OAuth 授權。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved