網站文章常引用外部連結或圖片。若不加控管,會導致:
解決方案:識別非本站域名的 `` 與 `` 標籤,自動注入 `rel="external nofollow"`。
<?php
/**
* 為內容中的外部連結與圖片添加 nofollow
*
* @param string $content 文章內容 HTML
* @param string $domain 本站域名 (不含協議與尾斜線,如: www.example.com)
* @return string 處理後的 HTML
*/
function content_nofollow($content, $domain) {
// 1. 處理超連結
if (preg_match_all('/href\s*=\s*["\']([^"\']+)["\']/i', $content, $matches)) {
foreach ($matches[1] as $url) {
// 過濾:非本站域名、非錨點、非 JavaScript、非郵件
if (
stripos($url, $domain) === false &&
strpos($url, '#') !== 0 &&
stripos($url, 'javascript:') !== 0 &&
stripos($url, 'mailto:') !== 0
) {
// 避免重複添加
if (stripos($matches[0][array_search($url, $matches[1])], 'nofollow') === false) {
$content = str_replace(
$matches[0][array_search($url, $matches[1])],
'href="' . $url . '" rel="external nofollow"',
$content
);
}
}
}
}
// 2. 處理圖片 (圖片通常不需 nofollow,但可加 referrerpolicy)
// 現代 SEO 建議:圖片盡量本地化。此處示範加上 referrerpolicy 防盜鏈洩露 referrer
if (preg_match_all('/src\s*=\s*["\']([^"\']+)["\']/i', $content, $matches)) {
foreach ($matches[1] as $url) {
if (stripos($url, $domain) === false) {
if (stripos($matches[0][array_search($url, $matches[1])], 'referrerpolicy') === false) {
$content = str_replace(
$matches[0][array_search($url, $matches[1])],
'src="' . $url . '" referrerpolicy="no-referrer"',
$content
);
}
}
}
}
return $content;
}
// 使用範例
$domain = 'www.example.com'; // 必須不帶 https:// 和尾部 /
$article_content = '<a href="https://external.com">外部連結</a> <img src="https://cdn.external.com/img.jpg">';
$safe_content = content_nofollow($article_content, $domain);
echo $safe_content;
正則處理 HTML 易因屬性順序、換行、單雙引號混用而遺漏。生產環境建議用 DOMDocument:
function content_nofollow_dom($html, $domain) {
$dom = new DOMDocument();
// 避免 HTML5 標籤報錯,加上 meta charset
$dom->loadHTML('<meta charset="utf-8">' . $html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($dom);
// 處理 a 標籤
foreach ($xpath->query('//a[@href]') as $link) {
$href = $link->getAttribute('href');
if (stripos($href, $domain) === false && !preg_match('/^(#|javascript:|mailto:)/i', $href)) {
$rel = $link->getAttribute('rel');
if (stripos($rel, 'nofollow') === false) {
$link->setAttribute('rel', trim($rel . ' external nofollow'));
}
}
}
// 處理 img 標籤
foreach ($xpath->query('//img[@src]') as $img) {
$src = $img->getAttribute('src');
if (stripos($src, $domain) === false) {
$img->setAttribute('referrerpolicy', 'no-referrer');
}
}
// 輸出 body 內容
$body = $dom->getElementsByTagName('body')->item(0);
return $dom->saveHTML($body);
}
rel="sponsored" (Google 規範)。rel="ugc"。