本文介紹一個功能完善的 PHP 下載類,支援斷點續傳、分塊下載、自動處理重定向與錯誤恢復。適用於大文件下載場景,透過 Socket 直接控制 HTTP 協議,避免記憶體溢出。
class downloader {
// 靜態入口方法
static function get($url, $save_file, $speed = 10240, $headers = [], $timeout = 10)
// 內部輔助方法
static function parse_url($url)
static function get_content_size($host, $port, $url_path, &$headers, $timeout)
static function download_content($host, $port, $url_path, $save_file, $content_length, $range_start, $speed, &$headers, $timeout)
static function build_header($action, $url_path, &$headers, $range_start = -1)
}
parse_url() 拆解協議、主機、埠、路徑與查詢字串。預設 Header 模擬瀏覽器行為,包含 Accept、User-Agent、Accept-Encoding、Host、Connection、Accept-Language。
發送 HEAD 請求獲取 Content-Length,若遇 3xx 重定向遞迴跟進。本地若已存在 .data 暫存檔,讀取上次下載位移;若文件大小不匹配或超出遠端大小,重置進度。
download_content() 組裝帶 Range: bytes={$range_start}- 的 GET 請求,透過 fsockopen 建立連線,逐塊讀取(預設 10KB)寫入檔案,並即時更新總位移。下載完成刪除暫存檔,異常時拋出異常保留進度。
try {
if (downloader::get('https://example.com/large.zip', 'large.zip')) {
echo '下載成功';
}
} catch (Exception $e) {
echo '下載失敗: ' . $e->getMessage();
}
fsockopen 與 stream_set_timeoutAccept-Ranges: bytesset_time_limit 或分段下載