減少 HTTP 請求數與傳輸體積是前端效能優化核心。本文提供一個 combine.php 進入點,支援:多檔案合併、Gzip/Deflate 壓縮、Etag/304 快取、快取檔案落地、User-Agent 相容性處理 (IE6 降級)、檔案型別驗證、基礎路徑配置。
t=j|c (js/css)、b=basePath、fs=file1,file2 (無副檔名)。mtime 生成 Etag,支援 If-None-Match 返回 304。Accept-Encoding 決定 gzip/deflate/none,IE6 降級不壓縮。cache-{etag}.js.gz) 存在則直接輸出。// 參數解析與安全檢查
$type = $_GET['t'] ?? ''; // j 或 c
$base = $_GET['b'] ? $_SERVER['DOCUMENT_ROOT'] . '/' . str_replace('.', '/', $_GET['b']) : $_SERVER['DOCUMENT_ROOT'];
$fs = $_GET['fs'] ?? '';
$ext = $type === 'j' ? '.js' : '.css';
$files = array_map(fn($f) => $base . '/' . $f . $ext, explode(',', $fs));
// 驗證每個檔案
foreach ($files as $f) {
if (!is_file($f) || strpos(realpath($f), realpath($base)) !== 0) {
http_response_code(404); exit('Not Found');
}
}
// Etag 與 304
$mtime = max(array_map('filemtime', $files));
$etag = $mtime . '-' . md5($fs);
header("Etag: \"$etag\"");
if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == "\"$etag\"") {
header('Content-Type: text/' . ($type === 'j' ? 'javascript' : 'css'));
header('Content-Length: 0');
http_response_code(304); exit;
}
// 壓縮輸出
$content = implode("\n\n", array_map('file_get_contents', $files));
$encoding = 'none';
if (strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false) $encoding = 'gzip';
elseif (strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate') !== false) $encoding = 'deflate';
if ($encoding !== 'none') {
$content = gzencode($content, 9, $encoding === 'gzip' ? FORCE_GZIP : FORCE_DEFLATE);
header("Content-Encoding: $encoding");
}
header('Content-Type: text/' . ($type === 'j' ? 'javascript' : 'css'));
header('Content-Length: ' . strlen($content));
echo $content;
// 快取落地 (需可寫目錄)
$cacheDir = $_SERVER['DOCUMENT_ROOT'] . '/public/cache';
$cacheFile = "$cacheDir/cache-$etag.$ext" . ($encoding !== 'none' ? ".$encoding" : '');
@file_put_contents($cacheFile, $content);
<!-- 合併 jquery.js + common.js --> <script src="combine.php?t=j&fs=lib.jquery,common"></script> <!-- 指定基礎路徑 public/js --> <script src="combine.php?t=j&b=public.js&fs=lib.jquery,common"></script> <!-- CSS 合併 --> <link rel="stylesheet" href="combine.php?t=c&fs=reset,layout,theme">
本方案適用於無建構流程的傳統 PHP 專案快速優化。