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中的CMS的涵义
Mar 11 PHP
微信扫描二维码登录网站代码示例
Dec 30 PHP
PHP实现图片压缩的两则实例
Jul 19 PHP
php中创建和调用webservice接口示例
Jul 25 PHP
一个完整的PHP类包含的七种语法说明
Jun 04 PHP
php实现的SSO单点登录系统接入功能示例分析
Oct 12 PHP
php实现跨域提交form表单的方法【2种方法】
Oct 17 PHP
Laravel框架路由设置与使用示例
Jun 12 PHP
PHP消息队列实现及应用详解【队列处理订单系统和配送系统】
May 20 PHP
PHP字符串中抽取子串操作实例分析
Jun 22 PHP
php时间戳转换代码详解
Aug 04 PHP
laravel 去掉index.php伪静态的操作方法
Oct 12 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/11/27 PHP
PHP 输出缓冲控制(Output Control)详解
2016/08/25 PHP
PHP弱类型语言中类型判断操作实例详解
2017/08/10 PHP
表单填写时用回车代替TAB的实现方法
2007/10/09 Javascript
web前端开发也需要日志
2010/12/09 Javascript
jquery中的过滤操作详细解析
2013/12/02 Javascript
javascript中定义类的方法汇总
2014/12/28 Javascript
Js为表单动态添加节点内容的方法
2015/02/10 Javascript
JavaScript设置获取和设置属性的方法
2015/03/04 Javascript
基于Jquery实现表单验证
2020/07/20 Javascript
javascript每日必学之封装
2016/02/23 Javascript
jQuery获取复选框被选中数量及判断选择值的方法详解
2016/05/25 Javascript
jQuery中each()、find()和filter()等节点操作方法详解(推荐)
2016/05/25 Javascript
分享JS数组求和与求最大值的方法
2016/08/11 Javascript
js移动焦点到最后位置的简单方法
2016/11/25 Javascript
JS实现的系统调色板完整实例
2016/12/21 Javascript
vue 监听某个div垂直滚动条下拉到底部的方法
2018/09/15 Javascript
加快Vue项目的开发速度的方法
2018/12/12 Javascript
jquery实现自定义树形表格的方法【自定义树形结构table】
2019/07/12 jQuery
js实现类选择器和name属性选择器的示例步骤
2021/02/07 Javascript
[01:33]PWL开团时刻DAY2-开雾与反开雾
2020/10/31 DOTA
用Python编写一个简单的FUSE文件系统的教程
2015/04/02 Python
利用python代码写的12306订票代码
2015/12/20 Python
浅谈Python实现2种文件复制的方法
2018/01/19 Python
Python实现的视频播放器功能完整示例
2018/02/01 Python
python求最大公约数和最小公倍数的简单方法
2020/02/13 Python
HTML5 canvas实现移动端上传头像拖拽裁剪效果
2016/03/14 HTML / CSS
Zavvi西班牙:电子游戏、极客服装、Blu-ray、Funko Pop等
2019/05/03 全球购物
什么是servlet链?
2014/07/13 面试题
外贸业务员的岗位职责
2013/11/23 职场文书
手机促销活动方案
2014/02/05 职场文书
大学中国梦演讲稿
2014/04/23 职场文书
党校毕业个人总结
2015/02/28 职场文书
学术会议开幕词
2016/03/03 职场文书
Python数据分析入门之数据读取与存储
2021/05/13 Python
Pandas实现批量拆分与合并Excel的示例代码
2022/05/30 Python