編輯器貼上外部圖片連結時,為避免防盜鏈、提升載入速度、確保資料可控,需自動下載遠程圖片至本地伺服器,並替換文章內容中的圖片連結。
$pattern = '/(src|SRC)=["\'\s]*((https?):\/\/[^\s"\'<>]+?\.(gif|jpg|jpeg|bmp|png))/isU'; preg_match_all($pattern, $content, $matches); $imageUrls = array_unique($matches[2]); // 去重
$basePath = $_SERVER['DOCUMENT_ROOT'] . '/uploads/images/';
$dateDir = $basePath . date('Ymd/');
$dateUrl = '/uploads/images/' . date('Ymd/');
if (!is_dir($dateDir)) {
mkdir($dateDir, 0755, true);
}
set_time_limit(0); // 移除執行時間限制
foreach ($imageUrls as $url) {
$url = trim($url);
$imageData = @file_get_contents($url);
if (!$imageData) continue;
// 產生唯一檔名:時間戳 + 隨機數 + 副檔名
$ext = strtolower(pathinfo($url, PATHINFO_EXTENSION));
$ext = in_array($ext, ['jpg','jpeg','png','gif','bmp']) ? $ext : 'jpg';
$fileName = date('YmdHis') . '_' . mt_rand(10000, 99999) . '.' . $ext;
$filePath = $dateDir . $fileName;
$fileUrl = $dateUrl . $fileName;
file_put_contents($filePath, $imageData);
// 替換文章內容中的原始 URL
$content = str_replace($url, $fileUrl, $content);
}
curl_multi 並發下載大量圖片timeout 避免卡死Content-Type 確認為圖片格式getimagesize() 二次驗證圖片有效性$success = 0; $failed = [];
foreach ($imageUrls as $url) {
try {
// 下載邏輯...
$success++;
} catch (Exception $e) {
$failed[] = ['url' => $url, 'error' => $e->getMessage()];
}
}
// 記錄失敗清單供人工處理
if ($failed) error_log('Image download failed: ' . json_encode($failed));
考慮使用成熟函式庫:
建立健全的遠程圖片本地化機制,不僅能提升網站效能與安全性,更能掌握內容資料的完整控制權。