PHP使用range协议实现输出文件断点续传代码实例


Posted in PHP onJuly 04, 2014

range协议用途:一般是用在断点续传的时候,但是实际的用户很大,例如你的web server需要输出一个大文件,那么用range可以分段输出,缓解压力。同时在提供音乐视频等服务时可以缓冲下载,如果用户中途关闭,可以节约网络带宽。

<?php

// 文件名
$filename = $_GET ['filename'];

// 文件路径
$location = 'media/' . $filename;

// 后缀
$extension = substr ( strrchr ( $filename, '.' ), 1 );

if ($extension == "mp3") {
	$mimeType = "audio/mpeg";
} else if ($extension == "ogg") {
	$mimeType = "audio/ogg";
}

if (! file_exists ( $location )) {
	header ( "HTTP/1.1 404 Not Found" );
	return;
}

$size = filesize ( $location );
$time = date ( 'r', filemtime ( $location ) );

$fm = @fopen ( $location, 'rb' );
if (! $fm) {
	header ( "HTTP/1.1 505 Internal server error" );
	return;
}

$begin = 0;
$end = $size - 1;

if (isset ( $_SERVER ['HTTP_RANGE'] )) {
	if (preg_match ( '/bytes=\h*(\d+)-(\d*)[\D.*]?/i', $_SERVER ['HTTP_RANGE'], $matches )) {
		// 读取文件,起始节点
		$begin = intval ( $matches [1] );

		// 读取文件,结束节点
		if (! empty ( $matches [2] )) {
			$end = intval ( $matches [2] );
		}
	}
}

if (isset ( $_SERVER ['HTTP_RANGE'] )) {
	header ( 'HTTP/1.1 206 Partial Content' );
} else {
	header ( 'HTTP/1.1 200 OK' );
}

header ( "Content-Type: $mimeType" );
header ( 'Cache-Control: public, must-revalidate, max-age=0' );
header ( 'Pragma: no-cache' );
header ( 'Accept-Ranges: bytes' );
header ( 'Content-Length:' . (($end - $begin) + 1) );

if (isset ( $_SERVER ['HTTP_RANGE'] )) {
	header ( "Content-Range: bytes $begin-$end/$size" );
}

header ( "Content-Disposition: inline; filename=$filename" );
header ( "Content-Transfer-Encoding: binary" );
header ( "Last-Modified: $time" );

$cur = $begin;

// 定位指针
fseek ( $fm, $begin, 0 );

while ( ! feof ( $fm ) && $cur <= $end && (connection_status () == 0) ) {
	print fread ( $fm, min ( 1024 * 16, ($end - $cur) + 1 ) );
	$cur += 1024 * 16;
}

range协议官方文档:http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

PHP 相关文章推荐
PHP4实际应用经验篇(2)
Oct 09 PHP
PHP取得一个类的属性和方法的实现代码
May 22 PHP
php数据结构与算法(PHP描述) 快速排序 quick sort
Jun 21 PHP
PHP If Else(elsefi) 语句
Apr 07 PHP
测试PHP连接MYSQL成功与否的代码
Aug 16 PHP
新浪SAE搭建PHP项目教程
Jan 28 PHP
PHP输出两个数字中间有多少个回文数的方法
Mar 23 PHP
php版微信js-sdk支付接口类用法示例
Oct 12 PHP
CakePHP框架Model函数定义方法示例
Aug 04 PHP
PHP面向对象程序设计之多态性的应用示例
Dec 19 PHP
PHP中PCRE正则解析代码详解
Apr 26 PHP
PHP新手指南
Apr 01 PHP
PHP实现对文本数据库的常用操作方法实例演示
Jul 04 #PHP
成为好程序员必须避免的5个坏习惯
Jul 04 #PHP
windows7下安装php的php-ssh2扩展教程
Jul 04 #PHP
windows7下安装php的imagick和imagemagick扩展教程
Jul 04 #PHP
ThinkPHP框架任意代码执行漏洞的利用及其修复方法
Jul 04 #PHP
php实现批量压缩图片文件大小的脚本
Jul 04 #PHP
PHP实现的英文名字全拼随机排号脚本
Jul 04 #PHP
You might like
解析PHP无限级分类方法及代码
2013/06/21 PHP
浅析Mysql 数据回滚错误的解决方法
2013/08/05 PHP
PHP使用strtotime计算两个给定日期之间天数的方法
2015/03/18 PHP
超强多功能php绿色集成环境详解
2017/01/25 PHP
如何让您的中波更粗更长 - 中波框形天线制作
2021/03/10 无线电
jQuery 瀑布流 绝对定位布局(二)(延迟AJAX加载图片)
2012/05/23 Javascript
Javascript合并表格中具有相同内容单元格示例
2013/08/11 Javascript
简单的Jquery遮罩层代码实例
2013/11/14 Javascript
node.js中的fs.readdirSync方法使用说明
2014/12/17 Javascript
ECMAScript中函数function类型
2015/06/03 Javascript
AngualrJS中每次$http请求时的一个遮罩层Directive
2016/01/26 Javascript
微信小程序 列表的上拉加载和下拉刷新的实现
2017/04/01 Javascript
Vue 多层组件嵌套二种实现方式(测试实例)
2017/09/08 Javascript
微信小程序的部署方法步骤
2018/09/04 Javascript
IE9 elementUI文件上传的问题解决
2018/10/17 Javascript
单线程JavaScript实现异步过程详解
2020/05/19 Javascript
[01:00:13]完美世界DOTA2联赛 LBZS vs Forest 第一场 11.07
2020/11/09 DOTA
Python设计模式之观察者模式实例
2014/04/26 Python
浅谈django开发者模式中的autoreload是如何实现的
2017/08/18 Python
python实现windows壁纸定期更换功能
2019/01/21 Python
pandas dataframe的合并实现(append, merge, concat)
2019/06/24 Python
详解python中docx库的安装过程
2019/11/08 Python
tensorflow 限制显存大小的实现
2020/02/03 Python
Python OpenCV去除字母后面的杂线操作
2020/07/05 Python
举例详解CSS3中的Transition
2015/07/15 HTML / CSS
HTML5 CSS3打造相册效果附源码下载
2014/06/16 HTML / CSS
澳大利亚最受欢迎的女士度假服装:Kabana Shop
2020/10/10 全球购物
你常见到的runtime exception
2016/09/05 面试题
.net工程师笔试题
2012/06/09 面试题
商铺门前三包责任书
2014/07/25 职场文书
父亲节感言
2015/08/03 职场文书
PyQt5 显示超清高分辨率图片的方法
2021/04/11 Python
python Polars库的使用简介
2021/04/21 Python
使用react-virtualized实现图片动态高度长列表的问题
2021/05/28 Javascript
springmvc直接不经过controller访问WEB-INF中的页面问题
2022/02/24 Java/Android
Windows server 2012 配置Telnet以及用法详解
2022/04/28 Servers