桌面應用或嵌入式裝置常需自動更新功能。本文提出一套基於版本號的增量更新架構,透過伺服端計算差分檔案,客戶端僅下載變動部分,大幅降低頻寬與時間成本。
1.0) 至伺服器。1.2)。up_to_date;否則計算 1.0 → 1.2 之間所有變更檔案。version_table +----+---------+------------+------------------+ | id | version | date | changed_files | +----+---------+------------+------------------+ | 1 | 1.0 | 2015-01-01 | | | 2 | 1.1 | 2015-01-05 | index.php | | 3 | 1.2 | 2015-02-05 | index.php|lib/inc.php | +----+---------+------------+------------------+
changed_files 欄位以 | 分隔多檔案,記錄該版本新增/修改的檔案路徑。
<?php
function buildIncrementalPackage(string $clientVersion, string $latestVersion): array {
// 1. 取得版本 ID 範圍
$startId = getVersionId($clientVersion); // e.g. 1
$endId = getVersionId($latestVersion); // e.g. 3
// 2. 彙總所有變更檔案
$allFiles = [];
for ($id = $startId + 1; $id <= $endId; $id++) {
$row = getVersionRow($id);
if (!empty($row['changed_files'])) {
$files = explode('|', $row['changed_files']);
$allFiles = array_merge($allFiles, $files);
}
}
// 3. 去重與過濾空值
$uniqueFiles = array_unique(array_filter($allFiles));
// 4. 打包壓縮 (此處略,實際可用 ZipArchive)
$packagePath = createZipPackage($uniqueFiles); // 回傳 zip 檔路徑
// 5. 產生 manifest.json 供客戶端驗證
$manifest = [
'version' => $latestVersion,
'files' => array_values($uniqueFiles),
'hash' => sha1_file($packagePath),
];
file_put_contents(dirname($packagePath) . '/manifest.json', json_encode($manifest));
return ['download_url' => $packagePath, 'manifest' => $manifest];
}
// 快取機制:同版本請求直接回傳已生成的套件路徑,避免重複打包。
?>
function checkUpdate():
currentVer = getLocalVersion()
response = httpPost("/api/update", {version: currentVer})
if response.status == "up_to_date":
return
downloadUrl = response.download_url
manifest = response.manifest
zipPath = download(downloadUrl)
verifyHash(zipPath, manifest.hash)
extract(zipPath, targetDir: APP_ROOT)
writeVersion(manifest.version)
restartApp()
對於大型二進位檔 (如 .exe, .so),可採用 bsdiff/bspatch 產生極小差分檔,進一步縮減下載體積。原理為二進位層面的差異編碼,適合頻繁更新的大型客戶端。
這套架構已在多個產品線驗證穩定,核心在於「版本鏈 + 差分彙總 + 快取複用」,既簡單又高效。根據實際業務量,可擴充為分散式 CDN 分發、灰度發布等進階功能。