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 相关文章推荐
MySQL相关说明
Jan 15 PHP
php中删除字符串中最先出现某个字符的实现代码
Feb 03 PHP
基于Linux调试工具strace与gdb的常用命令总结
Jun 03 PHP
解析isset与is_null的区别
Aug 09 PHP
php检测iis环境是否支持htaccess的方法
Feb 18 PHP
php ctype函数中文翻译和示例
Mar 21 PHP
浅谈PHP中Stream(流)
Jun 08 PHP
php header函数的常用http头设置
Jun 25 PHP
浅析PHP类的反射来实现依赖注入过程
Feb 06 PHP
PDO::rollBack讲解
Jan 29 PHP
laravel框架中间件简单使用方法示例
Jan 25 PHP
Git命令之分支详解
Mar 02 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模板类代码
2008/09/07 PHP
PHP 向右侧拉菜单实现代码,测试使用中
2009/11/03 PHP
php5 non-thread-safe和thread-safe这两个版本的区别分析
2010/03/13 PHP
PHP中=赋值操作符对不同数据类型的不同行为
2011/01/02 PHP
PHP将整个网站生成HTML纯静态网页的方法总结
2012/02/05 PHP
php 修改、增加xml结点属性的实现代码
2013/10/22 PHP
php curl简单采集图片生成base64编码(并附curl函数参数说明)
2019/02/15 PHP
javascript 面向对象编程基础 多态
2009/08/21 Javascript
文本域中换行符的替换示例
2014/03/04 Javascript
实例讲解JS中setTimeout()的用法
2016/01/28 Javascript
jQuery根据表单name获取值的方法
2016/05/24 Javascript
js简单获取表单中单选按钮值的方法
2016/08/23 Javascript
JavaScript 值类型和引用类型的初次研究(推荐)
2017/07/19 Javascript
js设置随机切换背景图片的简单实例
2017/11/12 Javascript
学习Vue组件实例
2018/04/28 Javascript
Spring boot 和Vue开发中CORS跨域问题解决
2018/09/05 Javascript
基于Node的Axure文件在线预览的实现代码
2019/08/28 Javascript
React.js组件实现拖拽排序组件功能过程解析
2020/04/27 Javascript
使用next.js开发网址缩短服务的方法
2020/06/17 Javascript
[04:40]2016国际邀请赛中国区预选赛全程TOP10镜头集锦
2016/07/01 DOTA
[02:42]完美大师赛主赛事淘汰赛第三日观众采访
2017/11/25 DOTA
[31:55]完美世界DOTA2联赛循环赛 IO vs GXR BO2第一场 11.04
2020/11/05 DOTA
[52:40]完美世界DOTA2联赛PWL S2 Magma vs GXR 第一场 11.29
2020/12/02 DOTA
Python+OpenCV目标跟踪实现基本的运动检测
2018/07/10 Python
Python分支语句与循环语句应用实例分析
2019/05/07 Python
Python协程操作之gevent(yield阻塞,greenlet),协程实现多任务(有规律的交替协作执行)用法详解
2019/10/14 Python
Django 自定义分页器的实现代码
2019/11/24 Python
Python autoescape标签用法解析
2020/01/17 Python
python_matplotlib改变横坐标和纵坐标上的刻度(ticks)方式
2020/05/16 Python
利用CSS3的特性改变文本选中时的颜色
2013/09/11 HTML / CSS
三星美国官网:Samsung美国
2017/02/06 全球购物
Smallable英国家庭概念店:设计师童装及家居装饰
2017/07/05 全球购物
工商企业管理应届生求职信
2013/11/03 职场文书
竞选班干部演讲稿300字
2014/08/20 职场文书
城南旧事观后感
2015/06/11 职场文书
windows11怎么查看自己安装的版本号? win11版本号的查看方法
2021/11/21 数码科技