業務背景
- 站內大量引用外站文章,原文鏈接失效產生死鏈,損害 SEO
- 新增文章入庫時已自動加
rel="nofollow" (見《增加對站點內容外部鏈接的過濾》)
- 存量數據需批量清洗,逐條編輯成本極高,需自動化腳本
處理邏輯
- 掃描文章表
content 字段
- 正則提取所有
href="..." 和 src="http:..."
- 判斷域名是否為本站域名 (
$config['url'])
- 非本站域名 → 注入
rel="external nofollow"
- 回寫更新數據庫
完整 PHP 實現代碼
<?php
// 引入框架核心/數據庫配置
require_once 'config.inc.php'; // 假設包含 $config, $db 對象
global $config, $db;
// 1. 讀取所有文章
$sql = "SELECT `id`, `content` FROM `{$db->prefix}article`";
$a_list = $db->query($sql);
// 2. 獲取並標準化本站域名 (去除尾部 /)
$domain = rtrim($config['url'], '/');
// 3. 逐條處理
foreach ($a_list as $a) {
$content = content_nofollow($a['content'], $domain);
update_a($a['id'], $content);
}
exit;
function update_a($id, $content) {
global $db;
// 使用參數化查詢防注入 (此處簡化為 addslashes,生產請用 PDO/預處理)
$safe_content = addslashes($content);
$sql = "UPDATE `{$db->prefix}article` SET `content`='{$safe_content}' WHERE `id`={$id}";
if ($db->execute($sql)) {
echo $id . ' 更新成功!<br />';
}
}
// 核心清洗函數
function content_nofollow($content, $domain) {
// 1. 處理超鏈接 href
preg_match_all('/href="(.*?)"/', $content, $matches);
if ($matches) {
foreach ($matches[1] as $val) {
// 非本站域名且未包含 nofollow
if (strpos($val, $domain) === false && strpos($val, 'nofollow') === false) {
$content = str_replace('href="'.$val.'"', 'href="'.$val.'" rel="external nofollow"', $content);
}
}
}
// 2. 處理圖片 src (僅處理 http/https 外鏈圖片)
preg_match_all('/src="(https?:.*?)"/', $content, $matches);
if ($matches) {
foreach ($matches[1] as $val) {
if (strpos($val, $domain) === false && strpos($val, 'nofollow') === false) {
$content = str_replace('src="'.$val.'"', 'src="'.$val.'" rel="external nofollow"', $content);
}
}
}
return $content;
}
?>
關鍵點解析
| 點 | 說明 |
| 正則貪婪/非貪婪 | .*? 非貪婪匹配,確保精確提取單個屬性值 |
| 域名匹配 | strpos($val, $domain) === false 嚴格判斷非本站 (需確保 $domain 含協議如 https://www.ledaokj.com) |
| 去重保護 | 檢查 strpos($val, 'nofollow') === false 避免重複注入導致 HTML 失效 |
| 圖片 src 處理 | 正則 /src="(https?:.*?)"/ 僅針對外鏈圖片,本地相對路徑不處理 |
| SQL 注入防護 | 示例用 addslashes 簡化,**生產環境必須使用預處理語句 (PDO/Prepared Statements)** |
| 事務與批次 | 大量數據建議分批 (如每 100 條) 提交,避免長事務鎖表/超時 |
執行效果示例
-- 原始
<a href="https://www.53sj.net/article-6-1.html">外站文章</a>
<img src="https://www.53sj.net/data/attachment/block/d3/d34780d1fca3d6b7960a7eb7a2c4c0d3.jpg">
-- 清洗後
<a href="https://www.53sj.net/article-6-1.html" rel="external nofollow">外站文章</a>
<img src="https://www.53sj.net/data/attachment/block/d3/d34780d1fca3d6b7960a7eb7a2c4c0d3.jpg" rel="external nofollow">
擴展建議
- 增加
target="_blank" 統一外鏈新窗口打開
- 記錄清洗日志 (ID、原始鏈接、處理時間) 便於審計回滾
- 對於極大表,改用
SELECT ... LIMIT offset, size 分頁游標處理
- 結合定時任務 (crontab) 定期增量清洗新增數據