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

PHP 批量下載遠端圖片並自動替換為本地路徑的完整實現

     編輯:PHP 相關知識

需求場景

採集文章時,內容中的圖片多為外部連結。為避免防盜鏈、提升載入速度與資料可控性,需將圖片下載至本地伺服器,並將文章內容的 src 屬性替換為本地路徑。

核心函數:replaceimg()

/**
 * 獲取並替換文章中的圖片路徑
 * @param string $xstr 文章內容(HTML)
 * @param string $keyword 圖片儲存子目錄關鍵字(如 upimg)
 * @param string $oriweb 原網站域名(相對路徑時用於拼接完整 URL,無則傳 null)
 * @return string 處理後的文章內容
 */
function replaceimg($xstr, $keyword, $oriweb) {
    $basedir = dirname(__FILE__);
    // 建立按年月分類的儲存目錄
    $d = date('Ym', time());
    $dirslsitss = $basedir . '/../uploads/' . $keyword . '/' . $d;
    if (!is_dir($dirslsitss)) {
        @mkdir($dirslsitss, 0777, true);
    }

    // 正則匹配所有 img 標籤的 src
    preg_match_all('#<img.*?src=["\']([^"\']+)["\'][^>]*>#i', $xstr, $match);

    foreach ($match[1] as $imgurl) {
        // 判斷是絕對路徑還是相對路徑
        if (strpos($imgurl, 'http') === 0) {
            $arcurl = $imgurl;
        } else {
            $arcurl = $oriweb . $imgurl;
        }

        // 下載圖片
        $img = @file_get_contents($arcurl);
        if (!empty($img)) {
            // 產生唯一檔名:時間戳 + 隨機數 + .jpg
            $fileimgname = time() . "-" . rand(1000, 9999) . ".jpg";
            $filecachs = $dirslsitss . "/" . $fileimgname;
            $fanhuistr = file_put_contents($filecachs, $img);

            // 組合本地相對路徑(供資料庫存儲或前端引用)
            $saveimgfile = "/uploads/$keyword/" . $d . "/" . $fileimgname;

            // 替換文章內容中的原始 URL
            $xstr = str_replace($imgurl, $saveimgfile, $xstr);
        }
    }
    return $xstr;
}

關鍵點解析

  • 正則模式:`#]*>#i` 兼容單雙引號,非貪婪匹配。
  • 目錄結構:`uploads/關鍵字/年月/` 避免單一目錄檔案過多影響效能。
  • 檔名唯一性:`time()-rand()` 簡單有效,高併發建議改用 `uniqid()` 或雜湊。
  • 錯誤處理:`@file_get_contents` 抑制警告,實際專案建議加入 `try-catch`、超時設定、檔案類型驗證(`getimagesize`)。
  • 相對/絕對路徑:支援 `` 等相對路徑,需傳入 `$oriweb`(如 `https://example.com`)。

進階優化建議

  1. 使用 cURL 替代 `file_get_contents`,支援 HTTPS、重定向、User-Agent 設定。
  2. 下載前檢查 `Content-Type` 與 `Content-Length`,過濾非圖片或過大檔案。
  3. 引入快取機制:相同 URL 不重複下載(資料庫記錄 URL 對應本地路徑)。
  4. 非同步處理:採集入庫時只記錄需下載的 URL,由背景 Worker(如 Gearman、Swoole、Queue)處理下載與替換。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved