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+apc实现上传进度条且在IE7下不显示的问题解决方法
Apr 25 PHP
如何使用Strace调试工具
Jun 03 PHP
php 魔术方法详解
Nov 11 PHP
Laravel 5框架学习之向视图传送数据
Apr 08 PHP
简单谈谈php中的unicode和utf8编码
Jun 10 PHP
PHP程序中使用adodb连接不同数据库的代码实例
Dec 19 PHP
PHP扩展框架之Yaf框架的安装与使用
May 18 PHP
PHP QRCODE生成彩色二维码的方法
May 19 PHP
php实现给二维数组中所有一维数组添加值的方法
Feb 04 PHP
学习thinkphp5.0验证类使用方法
Nov 16 PHP
Laravel框架实现修改登录和注册接口数据返回格式的方法
Aug 17 PHP
Laravel 错误提示本地化的实现
Oct 22 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
打造计数器DIY三步曲(上)
2006/10/09 PHP
php写的简易聊天室代码
2011/06/04 PHP
php Hex RGB颜色值互换的使用
2013/05/10 PHP
laravel框架中间件简单使用方法示例
2020/01/25 PHP
25个好玩的JavaScript小游戏分享
2011/04/22 Javascript
JS定时器实例详细分析
2013/10/11 Javascript
jQuery操作CheckBox的方法介绍(选中,取消,取值)
2014/02/04 Javascript
JavaScript 基本概念
2015/01/20 Javascript
javascript关于open.window子页面执行完成后刷新父页面的问题分析
2015/04/27 Javascript
jquery+ajax请求且带返回值的代码
2015/08/12 Javascript
JQuery通过AJAX从后台获取信息显示在表格上并支持行选中
2015/09/15 Javascript
javascript的理解及经典案例分析
2016/05/20 Javascript
JavaScript使用简单正则表达式的数据验证功能示例
2017/01/13 Javascript
Vuex之理解Getters的用法实例
2017/04/19 Javascript
基于jQuery和CSS3实现APPLE TV海报视差效果
2017/06/16 jQuery
jQuery响应滚动条事件功能示例
2017/10/14 jQuery
angularJs在多个控制器中共享服务数据的方法
2018/09/30 Javascript
vue项目中使用vue-i18n报错的解决方法
2019/01/13 Javascript
Vue.js特性Scoped Slots的浅析
2019/02/20 Javascript
JavaScript实现获取两个排序数组的中位数算法示例
2019/02/26 Javascript
Python中使用PIPE操作Linux管道
2015/02/04 Python
Python字符串拼接、截取及替换方法总结分析
2016/04/13 Python
python定时检测无响应进程并重启的实例代码
2019/04/22 Python
Python3.7实现验证码登录方式代码实例
2020/02/14 Python
如何在python中处理配置文件代码实例
2020/09/27 Python
如何利用CSS3制作3D效果文字具体实现样式
2013/05/02 HTML / CSS
2014年大学生就业规划书
2014/04/04 职场文书
《有趣的发现》教学反思
2014/04/15 职场文书
搞笑车尾标语
2014/06/23 职场文书
学校副校长四风对照检查材料整改措施
2014/09/25 职场文书
2014年服务员个人工作总结
2014/12/23 职场文书
2015年关爱留守儿童工作总结
2015/05/22 职场文书
国王的演讲观后感
2015/06/03 职场文书
监护人证明
2015/06/19 职场文书
一文读懂navicat for mysql基础知识
2021/05/31 MySQL
Nginx的gzip相关介绍
2022/05/11 Servers