在 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 文件操作函数,可以实现客户端断点续传文件下载功能。