前端開發常需從既有 CSS 提取背景圖、字體等資源。本文示範完整流程:解析 CSS、提取 url() 路徑、解析相對/絕對 URL、批量下載並重組本地路徑。
<?php
function extractCssUrls(string $css): array {
// 匹配 url("...") url('...') url(...) 格式
// 排除 data: URI、空值
$pattern = '/url\(\s*[\'"]?([^\'")\s]+)[\'"]?\s*\)/i';
preg_match_all($pattern, $css, $matches);
$urls = [];
foreach ($matches[1] as $url) {
// 過濾 data: URI、空值、非圖片/字體資源
if (str_starts_with($url, 'data:')) continue;
if (empty(trim($url))) continue;
$urls[] = $url;
}
return array_unique($urls);
}
?>
<?php
function resolveCssUrl(string $cssUrl, string $baseUrl): string {
$base = rtrim(dirname($baseUrl), '/') . '/';
if (str_starts_with($cssUrl, 'https://') || str_starts_with($cssUrl, 'https://') || str_starts_with($cssUrl, '//')) {
return str_starts_with($cssUrl, '//') ? 'https:' . $cssUrl : $cssUrl;
}
if (str_starts_with($cssUrl, '/')) {
$parsed = parse_url($baseUrl);
return $parsed['scheme'] . '://' . $parsed['host'] . $cssUrl;
}
return $base . ltrim($cssUrl, './');
}
?>
<?php
set_time_limit(0);
ini_set('memory_limit', '256M');
$cssUrl = 'https://example.com/assets/style.css';
$saveDir = __DIR__ . '/downloaded_assets';
$cssContent = file_get_contents($cssUrl);
if ($cssContent === false) {
die("無法取得 CSS: $cssUrl");
}
// 1. 提取 URL
$relativeUrls = extractCssUrls($cssContent);
echo "發現 " . count($relativeUrls) . " 個資源\n";
// 2. 解析絕對 URL 並下載
$urlMap = []; // 原始 URL => 本地相對路徑
$success = $failed = 0;
foreach ($relativeUrls as $relUrl) {
$absUrl = resolveCssUrl($relUrl, $cssUrl);
$filename = basename(parse_url($absUrl, PHP_URL_PATH));
$localPath = "$saveDir/$filename";
// 避免檔名衝突
$counter = 1;
$origName = $filename;
while (file_exists($localPath)) {
$info = pathinfo($origName);
$filename = $info['filename'] . "_$counter." . ($info['extension'] ?? '');
$localPath = "$saveDir/$filename";
$counter++;
}
// 3. 下載(使用前文 cURL 版本)
$result = downloadImage($absUrl, $saveDir);
if ($result['success']) {
$urlMap[$relUrl] = $filename;
$urlMap[$absUrl] = $filename; // 兩種格式都對應
$success++;
echo "✓ $filename\n";
} else {
$failed++;
echo "✗ $absUrl - {$result['error']}\n";
}
usleep(200000); // 0.2秒禮貌延遲
}
// 4. 重寫 CSS 使用本地路徑
$newCss = $cssContent;
foreach ($urlMap as $orig => $local) {
$newCss = str_replace($orig, $local, $newCss);
}
file_put_contents("$saveDir/style.local.css", $newCss);
echo "\n完成: 成功 $success, 失敗 $failed\n";
echo "本地 CSS: $saveDir/style.local.css\n";
function downloadImage(string $url, string $dir): array { /* 前文 cURL 實作 */ }
function extractCssUrls(string $css): array { /* 上方實作 */ }
function resolveCssUrl(string $cssUrl, string $baseUrl): string { /* 上方實作 */ }
?>
woff2、woff、ttf 同樣適用?v=1.2,下載時保留但檔名需處理