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 相关文章推荐
让PHP支持页面回退的两种方法
Jan 10 PHP
CodeIgniter php mvc框架 中国网站
May 26 PHP
php中获取关键词及所属来源搜索引擎名称的代码
Feb 15 PHP
php生成N个不重复的随机数实例
Nov 12 PHP
php生成数组的使用示例 php全组合算法
Jan 16 PHP
php实现图片添加描边字和马赛克的方法
Dec 10 PHP
php文件上传类完整实例
May 14 PHP
Yii2实现同时搜索多个字段的方法
Aug 10 PHP
SAE实时日志接口SDK用法示例
Oct 09 PHP
PHP抓取远程图片(含不带后缀的)教程详解
Oct 21 PHP
thinkphp分页集成实例
Jul 24 PHP
PHP实现单条sql执行多个数据的insert语句方法
Oct 11 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数组的一些常见操作汇总
2011/07/17 PHP
PHP新手用的Insert和Update语句构造类
2012/03/31 PHP
Thinkphp3.2.3分页使用实例解析
2016/07/28 PHP
Yii2实现ActiveForm ajax提交
2017/05/26 PHP
PHP封装curl的调用接口及常用函数详解
2018/05/31 PHP
得到jQuery detach()后节点中的某个值实现代码
2013/02/05 Javascript
JQuery的$命名冲突详细解析
2013/12/28 Javascript
js实现连个数字相加而不是拼接的方法
2014/02/23 Javascript
window.location不跳转的问题解决方法
2014/04/17 Javascript
jQuery源码解读之addClass()方法分析
2015/02/20 Javascript
javascript实现五星评价代码(源码下载)
2015/08/11 Javascript
js实现3D图片逐张轮播幻灯片特效代码分享
2015/09/09 Javascript
Javascript对象字面量的理解
2016/06/22 Javascript
javascript表达式和运算符详解
2017/02/07 Javascript
Bootstrap导航条学习使用(二)
2017/02/08 Javascript
JS实现下拉菜单列表与登录注册弹窗效果
2017/08/10 Javascript
微信小程序设置滚动条过程详解
2019/07/25 Javascript
JS数组及对象遍历方法代码汇总
2020/06/16 Javascript
Vue实现boradcast和dispatch的示例
2020/11/13 Javascript
python实现哈希表
2014/02/07 Python
numpy排序与集合运算用法示例
2017/12/15 Python
基于DataFrame筛选数据与loc的用法详解
2018/05/18 Python
python实现扫描局域网指定网段ip的方法
2019/04/16 Python
Django关于admin的使用技巧和知识点
2020/02/10 Python
Python基于callable函数检测对象是否可被调用
2020/10/16 Python
用Python自动清理电脑内重复文件,只要10行代码(自动脚本)
2021/01/09 Python
借助HTML5 Canvas来绘制三角形和矩形等多边形的方法
2016/03/14 HTML / CSS
AmazeUI 图标的示例代码
2020/08/13 HTML / CSS
汉语言文学职业规划
2014/02/14 职场文书
超市活动计划书
2014/04/24 职场文书
四风个人对照检查材料思想汇报
2014/09/25 职场文书
新郎婚礼致辞
2015/07/27 职场文书
《红领巾真好》教学反思
2016/02/16 职场文书
大学生暑期社会实践的个人总结!
2019/07/17 职场文书
python使用torch随机初始化参数
2022/03/22 Python
python实现简单的三子棋游戏
2022/04/28 Python