在PHP 中,處理文件下載時,斷點續傳是一項常見需求。它允許用戶在下載過程中斷開後,能夠從中斷的位置繼續下載,避免重新下載整個文件。通常實現斷點續傳的關鍵在於HTTP 頭的處理和服務器對Range 請求的支持。
那麼, stream_context_set_params能否用來實現文件斷點續傳呢?如何配置?
stream_context_set_params是PHP 中用來為已有的流上下文設置參數的函數,常用於調整流的行為,比如超時、通知回調等。它的使用形式是:
stream_context_set_params(resource $stream_context, array $params): bool
參數中可以包含:
notification :設置回調函數
timeout :設置超時時間(秒)
blocking :是否阻塞流
斷點續傳的實現主要依賴於HTTP 協議中的Range頭,服務器根據請求頭返回對應字節範圍的數據。例如:
Range: bytes=1000-
表示客戶端想從第1000字節開始下載。
服務器收到這樣的請求後,會返回狀態碼206 Partial Content ,並在響應頭中帶上Content-Range ,告訴客戶端返回了文件的哪個部分。
嚴格來說, stream_context_set_params本身並不是設計用來處理HTTP 頭部的,它是用來設置流的參數,無法直接用來配置HTTP 請求頭里的Range ,也無法處理服務器端的響應狀態碼和分段傳輸。
如果你想在PHP 中發起支持斷點續傳的HTTP 請求,應該使用stream_context_create配合HTTP 選項來設置請求頭,比如:
$options = [
'http' => [
'method' => 'GET',
'header' => "Range: bytes=1000-\r\n",
]
];
$context = stream_context_create($options);
$file = file_get_contents('http://m66.net/path/to/file', false, $context);
這樣客戶端就能請求文件從指定字節開始下載。
<?php
$start = 1000; // 從第1000字節開始下載
$options = [
'http' => [
'method' => 'GET',
'header' => "Range: bytes=$start-\r\n",
'ignore_errors' => true, // 允許接收 206 響應
]
];
$context = stream_context_create($options);
$url = 'http://m66.net/path/to/largefile.zip';
$fileContent = file_get_contents($url, false, $context);
// 可以將 $fileContent 追加到已有文件,實現續傳合併
file_put_contents('localfile.zip', $fileContent, FILE_APPEND);
?>
在上面例子中,重點是通過http選項裡的header添加Range ,讓服務器返回部分內容。 stream_context_set_params並沒有被使用,因為它不負責設置請求頭。
客戶端發起帶Range 頭的請求只是斷點續傳的第一步,服務器必須正確支持並響應帶Range 的請求。
服務器需返回狀態碼206 Partial Content
服務器需正確設置Content-Range頭部
服務器支持斷點讀取文件
若服務器不支持,客戶端請求Range 頭仍會返回整個文件。
stream_context_set_params主要用來設置流的參數,不用於設置HTTP 請求頭,不能直接實現斷點續傳。
要實現斷點續傳,應該用stream_context_create並在http選項中設置Range請求頭。
斷點續傳還需服務器正確支持Range 請求。
結合PHP 文件操作函數,可以實現客戶端斷點續傳文件下載功能。