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 相关文章推荐
重新封装zend_soap实现http连接安全认证的php代码
Jan 12 PHP
php学习笔记 数组的常用函数
Jun 13 PHP
PHP 获取MySQL数据库里所有表的实现代码
Jul 13 PHP
PHP spl_autoload_register实现自动加载研究
Dec 06 PHP
php防止sql注入之过滤分页参数实例
Nov 03 PHP
PHP框架Laravel学习心得体会
Oct 28 PHP
php实现基于pdo的事务处理方法示例
Jul 21 PHP
PHP中递归的实现实例详解
Nov 14 PHP
PHP中数组转换为SimpleXML教程
Jan 27 PHP
PHP自动载入类文件函数__autoload的使用方法
Mar 25 PHP
php写入文件不覆盖的实例讲解
Sep 17 PHP
php获取是星期几的的一些常用姿势
Dec 15 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入门学习知识点五 关于php数组的几个基本操作
2011/07/14 PHP
使用PHP接收POST数据,解析json数据
2013/06/28 PHP
php使用gzip压缩传输js和css文件的方法
2015/07/29 PHP
CodeIgniter读写分离实现方法详解
2016/01/20 PHP
关于Laravel Route重定向的一个注意点
2017/01/16 PHP
yii2学习教程之5种内置行为类详解
2017/08/03 PHP
PHP微信开发之微信录音临时转永久存储
2018/01/26 PHP
PHP中使用mpdf 导出PDF文件的实现方法
2018/10/22 PHP
用javascript实现画板的代码
2007/09/05 Javascript
js表数据排序 sort table data
2009/02/18 Javascript
一个关于jqGrid使用的小例子(行按钮)
2011/11/04 Javascript
JavaScript将Table导出到Excel实现思路及代码
2013/03/13 Javascript
每天一篇javascript学习小结(面向对象编程)
2015/11/20 Javascript
js实现符合国情的日期插件详解
2017/01/19 Javascript
Angularjs 依赖压缩及自定义过滤器写法
2017/02/04 Javascript
详解基于node的前端项目编译时内存溢出问题
2017/08/01 Javascript
js实现扫雷小程序的示例代码
2017/09/27 Javascript
js Element Traversal规范中的元素遍历方法
2018/04/19 Javascript
使用javascript函数编写简单银行取钱存钱流程
2018/05/26 Javascript
NodeJs 实现简单WebSocket即时通讯的示例代码
2019/08/05 NodeJs
Vue监听滚动实现锚点定位(双向)示例
2019/11/13 Javascript
vue element-ui读取pdf文件的方法
2019/11/26 Javascript
解决vue-router 切换tab标签关闭时缓存问题
2020/07/22 Javascript
vue中解决拖拽改变存在iframe的div大小时卡顿问题
2020/07/22 Javascript
在终端启动Python时报错的解决方案
2020/11/20 Python
五分钟学会怎么用python做一个简单的贪吃蛇
2021/01/12 Python
咖啡为什么会有酸味?你喝到的咖啡為什麼是酸的?
2021/03/17 冲泡冲煮
html5使用canvas实现图片下载功能的示例代码
2017/08/26 HTML / CSS
html5 worker 实例(二) 图片变换效果
2013/06/24 HTML / CSS
Revolution Beauty美国官网:英国知名化妆品网站
2018/07/23 全球购物
中专自我鉴定
2014/02/05 职场文书
中专毕业生的自荐书
2014/07/01 职场文书
大学团日活动新闻稿
2014/09/10 职场文书
民事调解书范文
2015/05/20 职场文书
JS实现页面炫酷的时钟特效示例
2022/08/14 Javascript
Fluentd搭建日志收集服务
2022/09/23 Servers