本文是为大家分享php支持断点续传、分块下载的类,供大家参考,具体内容如下
'*
static function parse_url($url) {
$url_info = parse_url($url);
if (!$url_info['host']) {
return false;
}
$url_info['port'] = $url_info['port'] ? $url_info['host'] : 80;
$url_info['request'] = $url_info['path'] . ($url_info['query'] ? '?' . $url_info['query'] : '');
return $url_info;
}
static function download_content($host, $port, $url_path, $save_file, $content_length, $range_start, $speed, &$headers, $timeout) {
$request = self::build_header('GET', $url_path, $headers, $range_start);
$fsocket = @fsockopen($host, $port, $errno, $errstr, $timeout);
stream_set_blocking($fsocket, TRUE);
stream_set_timeout($fsocket, $timeout);
fwrite($fsocket, $request);
$status = stream_get_meta_data($fsocket);
if ($status['timed_out']) {
throw new Exception('Socket Connect Timeout');
}
$is_header_end = 0;
$total_size = $range_start;
$file_fp = fopen($save_file, 'a+');
while (!feof($fsocket)) {
if (!$is_header_end) {
$line = @fgets($fsocket);
if (in_array($line, array("n", "rn"))) {
$is_header_end = 1;
}
continue;
}
$resp = fread($fsocket, $speed);
$read_length = strlen($resp);
if ($resp === false || $content_length < $total_size + $read_length) {
fclose($fsocket);
fclose($file_fp);
throw new Exception('Socket I/O Error Or File Was Changed');
}
$total_size += $read_length;
fputs($file_fp, $resp);
// check file end
if ($content_length == $total_size) {
break;
}
sleep(1);
// for test
//break;
}
fclose($fsocket);
fclose($file_fp);
return true;
}
static function get_content_size($host, $port, $url_path, &$headers, $timeout) {
$request = self::build_header('HEAD', $url_path, $headers);
$fsocket = @fsockopen($host, $port, $errno, $errstr, $timeout);
stream_set_blocking($fsocket, TRUE);
stream_set_timeout($fsocket, $timeout);
fwrite($fsocket, $request);
$status = stream_get_meta_data($fsocket);
$length = 0;
if ($status['timed_out']) {
return 0;
}
while (!feof($fsocket)) {
$line = @fgets($fsocket);
if (in_array($line, array("n", "rn"))) {
break;
}
$line = strtolower($line);
// get location
if (substr($line, 0, 9) == 'location:') {
$location = trim(substr($line, 9));
$url_info = self::parse_url($location);
if (!$url_info['host']) {
return 0;
}
fclose($fsocket);
return self::get_content_size($url_info['host'], $url_info['port'], $url_info['request'], $headers, $timeout);
}
// get content length
if (strpos($line, 'content-length:') !== false) {
list(, $length) = explode('content-length:', $line);
$length = (int)trim($length);
}
}
fclose($fsocket);
return $length;
}
static function build_header($action, $url_path, &$headers, $range_start = -1) {
$out = $action . " {$url_path} HTTP/1.0rn";
foreach ($headers as $hkey => $hval) {
$out .= $hkey . ': ' . $hval . "rn";
}
if ($range_start > -1) {
$out .= "Accept-Ranges: bytesrn";
$out .= "Range: bytes={$range_start}-rn";
}
$out .= "rn";
return $out;
}
}
#use age
?>
以上就是本文的全部内容,希望对大家的学习有所帮助。



