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反弹shell实现代码
Apr 22 PHP
php网站来路获取代码(针对搜索引擎)
Jun 08 PHP
php开发环境配置记录
Jan 14 PHP
PHP 日,周,月点击排行统计
Jan 11 PHP
PHP内核探索:变量概述
Jan 30 PHP
php判断ip黑名单程序代码实例
Feb 24 PHP
php实现水仙花数的4个示例分享
Apr 08 PHP
PHP把MSSQL数据导入到MYSQL的方法
Dec 27 PHP
Smarty foreach控制循环次数的一些方法
Jul 01 PHP
实现WordPress主题侧边栏切换功能的PHP脚本详解
Dec 14 PHP
Yii使用DbTarget实现日志功能的示例代码
Jul 21 PHP
PHP执行linux命令6个函数代码实例
Nov 24 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代码的53条建议
2008/03/27 PHP
PHP重定向的3种方式
2013/03/07 PHP
php编程每天必学之验证码
2016/03/03 PHP
thinkPHP5.0框架整体架构总览【应用,模块,MVC,驱动,行为,命名空间等】
2017/03/25 PHP
PHP基于timestamp和nonce实现的防止重放攻击方案分析
2019/07/26 PHP
jQuery获取文本节点之 text()/val()/html() 方法区别
2011/03/01 Javascript
JavaScript中发布/订阅模式的简单实例
2014/11/05 Javascript
使用 TypeScript 重新编写的 JavaScript 坦克大战游戏代码
2015/04/07 Javascript
js实现Select列表各项上移和下移的方法
2015/08/14 Javascript
javascript实现表单验证
2016/01/29 Javascript
BootStrap实现手机端轮播图左右滑动事件
2016/10/13 Javascript
jQuery实现联动下拉列表查询框
2017/01/04 Javascript
jQuery进阶实践之利用最优雅的方式如何写ajax请求
2017/12/20 jQuery
js生成word中图片处理方法
2018/01/06 Javascript
Nuxt.js踩坑总结分享
2018/01/18 Javascript
详解如何在项目中使用jest测试react native组件
2018/02/09 Javascript
Vue时间轴 vue-light-timeline的用法说明
2020/10/29 Javascript
解决VantUI popup 弹窗不弹出或无蒙层的问题
2020/11/03 Javascript
[00:52]DOTA2第二届亚洲邀请赛预选赛宣传片
2017/01/13 DOTA
python实现数通设备端口监控示例
2014/04/02 Python
利用python模拟sql语句对员工表格进行增删改查
2017/07/05 Python
Python xlwt设置excel单元格字体及格式
2020/04/18 Python
python opencv 批量改变图片的尺寸大小的方法
2019/06/28 Python
基于sklearn实现Bagging算法(python)
2019/07/11 Python
Python爬取腾讯视频评论的思路详解
2019/12/19 Python
Python warning警告出现的原因及忽略方法
2020/01/31 Python
Keras自定义IOU方式
2020/06/10 Python
详解Selenium-webdriver绕开反爬虫机制的4种方法
2020/10/28 Python
您在慕尼黑的跑步商店:Lauf-bar
2019/10/11 全球购物
LINUX下线程,GDI类的解释
2012/04/17 面试题
20岁生日感言
2014/01/13 职场文书
辞职信怎么写
2015/02/27 职场文书
刑事上诉状范文
2015/05/22 职场文书
Django使用channels + websocket打造在线聊天室
2021/05/20 Python
vue3引入highlight.js进行代码高亮的方法实例
2022/04/08 Vue.js
Python实现科学占卜 让视频自动打码
2022/04/09 Python