本文提供一個增強版 enable_urls() 函數,自動識別文本中的 HTTP/HTTPS/FTP 鏈接、裸域名(www.開頭)、Email 地址,轉換為可點擊 HTML 鏈接,並修復原代碼正則缺陷、添加 XSS 防護、支持 HTTPS、優化性能。
.,匹配任意字符而非字面點。str_replace("LINKttp://", ...) 疑為殘留調試代碼,邏輯錯誤。htmlspecialchars(),直接輸出用戶內容導致 XSS 風險。ereg_replace(PHP 5.3+ 移除),應改用 preg_replace。<?php
function enableUrls(string $text): string {
// 1. 先對全文進行 HTML 轉義,防 XSS
$text = htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
// 2. 完整 URL 正則(HTTP/HTTPS/FTP,支持端口、路徑、查詢、錨點)
$urlRegex = '~
\b
(?: (?:https?|ftp):// ) # 協議
(?: [^\s<>"\']+ ) # 非空白/標籤字符
~ix';
$text = preg_replace_callback($urlRegex, function($m) {
$url = $m[0];
// 截斷過長 URL 顯示
$display = strlen($url) > 60 ? substr($url, 0, 57) . '...' : $url;
return "<a href='$url' target='_blank' rel='noopener noreferrer'>$display</a>";
}, $text);
// 3. 裸域名 www.開頭(無協議),補全 https://
$wwwRegex = '~
\b
( www\.[a-z0-9.-]+\.[a-z]{2,} (?:/[^\s<>"\']*)? ) # 域名+可選路徑
~ix';
$text = preg_replace_callback($wwwRegex, function($m) {
$url = 'https://' . $m[1];
$display = strlen($m[1]) > 50 ? substr($m[1], 0, 47) . '...' : $m[1];
return "<a href='$url' target='_blank' rel='noopener noreferrer'>$display</a>";
}, $text);
// 4. Email 地址
$emailRegex = '~
\b
[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}
\b
~ix';
$text = preg_replace_callback($emailRegex, function($m) {
$email = $m[0];
return "<a href='mailto:$email'>$email</a>";
}, $text);
return $text;
}
?>
<?php
$input = "訪問 https://example.com/path?q=1 或 www.test.org 頁面,聯繫 admin@site.com";
echo enableUrls($input);
/* 輸出:
訪問 <a href='https://example.com/path?q=1' target='_blank' rel='noopener noreferrer'>https://example.com/path?q=1</a>
或 <a href='https://www.test.org' target='_blank' rel='noopener noreferrer'>www.test.org</a> 頁面,
聯繫 <a href='mailto:admin@site.com'>admin@site.com</a>
*/
?>
| 項目 | 原代碼 | 增強版 |
|---|---|---|
| 正則引擎 | ereg_replace (已棄用) | preg_replace_callback (PCRE, 高性能) |
| URL 支持 | 僅 http/ftp、簡單路徑 | 完整 HTTP/HTTPS/FTP、端口、路徑、查詢、錨點 |
| 裸域名 | www. 簡單匹配 | 標準域名格式、自動補全 https:// |
| XSS 防護 | 無 | 全文 htmlspecialchars + 屬性值單引號包裹 |
| 長鏈接處理 | 無 | 顯示截斷 + title/tooltip 可擴展 |
| 安全屬性 | 無 | target='_blank' rel='noopener noreferrer' 防標籤劫持 |
DOMDocument 遍歷文本節點)。HTMLPurifier 進行全鏈路 XSS 防護。javascript:alert(1) 等)。