內容采集時,外站圖片鏈接可能失效、防盜鏈或影響加載速度。本文提供一個完整函數 replaceimg(),實現:正則提取 <img> 標籤 src → 判斷絕對/相對 URL → 下載圖片 → 按日期分目錄存儲 → 替換內容中的圖片路徑為本地路徑。
<?php
/**
* 獲取並替換文章中的圖片路徑到本地
* @param string $xstr 文章內容
* @param string $keyword 圖片存儲子目錄關鍵字(如分類名)
* @param string $oriweb 源站域名(用於補全相對路徑)
* @return string 替換後的內容
*/
function replaceimg($xstr, $keyword, $oriweb) {
// 1. 構建存儲目錄:/var/www/weblist/uploads/{$keyword}/YYYYMMDD
$d = date('Ymd', time());
$dir = '/var/www/weblist/uploads/' . $keyword . '/' . $d;
if (!is_dir($dir)) {
@mkdir($dir, 0777, true); // 遞歸創建
}
// 2. 正則匹配所有 img 標籤的 src
preg_match_all('#<img.*?src=["\']([^"\']+)["\'][^>]*>#i', $xstr, $match);
foreach ($match[1] as $imgUrl) {
// 3. 判斷絕對/相對 URL
$absoluteUrl = (stripos($imgUrl, 'http') === 0) ? $imgUrl : $oriweb . $imgUrl;
// 4. 下載圖片內容
$imgData = @file_get_contents($absoluteUrl);
if (empty($imgData)) continue; // 下載失敗跳過
// 5. 生成唯一文件名:時間戳-隨機數.jpg
$fileName = time() . '-' . rand(1000, 9999) . '.jpg';
$filePath = $dir . '/' . $fileName;
// 6. 保存到本地
if (file_put_contents($filePath, $imgData) === false) continue;
// 7. 構建 Web 可訪問路徑並替換
$webPath = "/uploads/$keyword/$d/$fileName";
$xstr = str_replace($imgUrl, $webPath, $xstr);
}
return $xstr;
}
| 步驟 | 說明 |
|---|---|
| 正則匹配 | #<img.*?src=["\']([^"\']+)["\'][^>]*>#i 兼容單雙引號、屬性順序不固定 |
| URL 判斷 | stripos($imgUrl, 'http') === 0 區分大小寫,兼容 https |
| 目錄結構 | 按關鍵字 + 日期分目錄,避免單目錄文件過多影響性能 |
| 文件命名 | 時間戳 + 4 位隨機數,極低衝突概率;統一 .jpg 後綴(可按 Content-Type 動態判斷) |
| 替換策略 | str_replace 直接替換原始 src,若同圖多次引用會全部替換 |
getimagesizefromstring() 驗證合法性,過濾非圖片內容//cdn.example.com/img.jpg、/path/img.jpg、../img.jpg 等情況<?php $content = '<p>文章內容<img src="/images/a.jpg"><img src="https://b.com/b.png"></p>'; $newContent = replaceimg($content, 'news', 'https://source-site.com'); // 結果:圖片已下載至 /var/www/weblist/uploads/news/20250115/... 並替換為 /uploads/news/20250115/...
將此函數集成至采集入庫流程,即可實現圖片自動本地化,提升站點穩定性與加載速度。