PHP 断点续传实例详解


Posted in PHP onNovember 11, 2017

在做一个案例,要给客户端做断点续传的服务,

断点续传主要是HTTP协议中的Content-Range报头。其理解如下:

Content-Range:响应资源的范围。可以在多次请求中标记请求的资源范围,在连接断开重新连接时,客户端只请求该资源未被下载的部分,而不是重新请求整个资源,实现了断点续传。迅雷就是基于这个原理,使用多线程分段读取网络上的资源,最后合并。关于PHP使用多线程实现断点续传稍后讨论。本文只实现简单的断点续传。

$file = $_GET['video'];
$size = filesize($file);
$size2 = $size-1;
$range = 0;
if(isset($_SERVER['HTTP_RANGE'])) { //http_range表示请求一个实体/文件的一个部分,用这个实现多线程下载和断点续传!
 header('HTTP /1.1 206 Partial Content');
 $range = str_replace('=','-',$_SERVER['HTTP_RANGE']);
 $range = explode('-',$range);
 $range = trim($range[1]);
 header('Content-Length:'.$size);
 header('Content-Range: bytes '.$range.'-'.$size2.'/'.$size);
} else {
 header('Content-Length:'.$size);
 header('Content-Range: bytes 0-'.$size2.'/'.$size);
}
header("Content-type: video/mp4");
header('Accenpt-Ranges: bytes');
header('application/octet-stream');
header("Cache-control: public");
header("Pragma: public");
// 解决在IE中下载时中文乱码问题
$ua = $_SERVER['HTTP_USER_AGENT'];
if(preg_match('/MSIE/',$ua)) { //表示正在使用 Internet Explorer。
 $ie_filename = str_replace('+','%20',urlencode($file));
 header('Content-Dispositon:attachment; filename='.$ie_filename);
} else {
 header('Content-Dispositon:attachment; filename='.$file);
}
$fp = fopen($file,'rb+');
fseek($fp,$range);    //fseek:在打开的文件中定位,该函数把文件指针从当前位置向前或向后移动到新的位置,新位置从文件头开始以字节数度量。成功则返回 0;否则返回 -1。注意,移动到 EOF 之后的位置不会产生错误。
while(!feof($fp)) {    //feof:检测是否已到达文件末尾 (eof)
 set_time_limit(0);    //控制运行时间
 print(fread($fp,1024));   //读取文件(可安全用于二进制文件,第二个参数:规定要读取的最大字节数)
 ob_flush();      //刷新PHP自身的缓冲区
 flush();      //刷新缓冲区的内容(严格来讲, 这个只有在PHP做为apache的Module(handler或者filter)安装的时候, 才有实际作用. 它是刷新WebServer(可以认为特指apache)的缓冲区.)
}
fclose($fp);

php中set_time_limit()函数运用

当你的页面有大量数据时,建议使用set_time_limit()来控制运行时间,默认是30s,所以需要你将执行时间加长点。

如 set_time_limit(800) ,其中将秒数设为0 ,表示持续运行到程序结束。如果要停止运行只能重启php-fpm(文章后面附有重启命令)

如:set_time_limit(0)表示持续运行到程序结束,但这个函数有些在window环境下有些人设置不成功,Linux下也可能会出现问题的,做好在逻辑代码加上try catch避免异常。

注意:这个函数的运行需要你关闭安全模式,在php.ini中将safe_mode = Off 安全模式设置为Off,否则将会出现下面错误:
Warning: set_time_limit() [function.set-time-limit]: Cannot set time limit in safe mode in

ps:在php.ini可以通过定义max_execution_time来设置PHP页面的最大执行时间。

在phpinfo()输出内容可以看到php相关配置。

Loaded Configuration File /etc/php.ini
set_time_limit(800);

这个函数指定了当前所在php脚本的最大执行时间为800秒,实际上

最大执行时间=php.ini里的max_execution_time数值 - 当前脚本已经执行的时间 + 设定值

假如php.ini里的max_execution_time=30,当前脚本已经执行5秒,则:

最大执行时间=30-5+800=825秒。

查看php运行目录命令:

which php
/usr/bin/php

查看php-fpm进程数:

ps aux | grep -c php-fpm

查看运行内存

/usr/bin/php -i|grep mem

重启php-fpm

/etc/init.d/php-fpm restart

总结

以上所述是小编给大家介绍的PHP 断点续传实例详解,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

PHP 相关文章推荐
用IE远程创建Mysql数据库的简易程序
Oct 09 PHP
php数组去重的函数代码
Feb 03 PHP
解析如何屏蔽php中的phpinfo()函数
Jun 06 PHP
PHP设计模式之解释器模式的深入解析
Jun 13 PHP
解析CI的AJAX分页 另类实现方法
Jun 27 PHP
PHP中cookie和session的区别实例分析
Aug 28 PHP
PHP7.0版本备注
Jul 23 PHP
PHP分页初探 一个最简单的PHP分页代码的简单实现
Jun 21 PHP
Yii实现的多级联动下拉菜单
Jul 13 PHP
Laravel中validation验证 返回中文提示 全局设置的方法
Sep 29 PHP
解决tp5在nginx下修改配置访问的问题
Oct 16 PHP
TP5(thinkPHP5)框架使用ajax实现与后台数据交互的方法小结
Feb 10 PHP
PHP+AJAX 投票器功能
Nov 11 #PHP
PHP实现双链表删除与插入节点的方法示例
Nov 11 #PHP
PHP实现基于栈的后缀表达式求值功能
Nov 10 #PHP
PHP实现基于图的深度优先遍历输出1,2,3...n的全排列功能
Nov 10 #PHP
PHP根据树的前序遍历和中序遍历构造树并输出后序遍历的方法
Nov 10 #PHP
PHP简单实现循环链表功能示例
Nov 10 #PHP
浅谈使用 Yii2 AssetBundle 中 $publishOptions 的正确姿势
Nov 08 #PHP
You might like
一个程序下载的管理程序(一)
2006/10/09 PHP
php array_intersect()函数使用代码
2009/01/14 PHP
php模拟js函数unescape的函数代码
2012/10/20 PHP
PHP递归调用的小技巧讲解
2013/02/19 PHP
解析用PHP读写音频文件信息的详解(支持WMA和MP3)
2013/05/10 PHP
PHP PDOStatement::debugDumpParams讲解
2019/01/30 PHP
php适配器模式简单应用示例
2019/10/23 PHP
jQuery中 delegate使用的问题
2015/07/03 Javascript
jquery彩色投票进度条简单实例演示
2020/07/23 Javascript
纯JS代码实现一键分享功能
2016/04/20 Javascript
js 实现数值的千分位及保存小数方法(推荐)
2016/08/01 Javascript
使用ES6语法重构React代码详解
2017/05/09 Javascript
EasyUI的DataGrid绑定Json数据源的示例代码
2017/12/16 Javascript
vue2.0的虚拟DOM渲染思路分析
2018/08/09 Javascript
对layui中表单元素的使用详解
2018/08/15 Javascript
Vue封装的可编辑表格插件方法
2018/08/28 Javascript
vue项目出现页面空白的解决方案
2019/10/31 Javascript
js实现无缝轮播图效果
2020/03/09 Javascript
nuxt 每个页面head标签内容设置方式
2020/11/05 Javascript
[01:07:17]EG vs Optic Supermajor 败者组 BO3 第一场 6.6
2018/06/07 DOTA
[01:20:05]DOTA2-DPC中国联赛 正赛 Ehome vs VG BO3 第二场 2月5日
2021/03/11 DOTA
实践Python的爬虫框架Scrapy来抓取豆瓣电影TOP250
2016/01/20 Python
Python装饰器用法实例总结
2018/05/26 Python
Python实现的简单计算器功能详解
2018/08/25 Python
对PyQt5中的菜单栏和工具栏实例详解
2019/06/20 Python
Python 脚本拉取 Docker 镜像问题
2019/11/10 Python
python @propert装饰器使用方法原理解析
2019/12/25 Python
Java 中访问数据库的步骤?Statement 和PreparedStatement 之间的区别?
2012/06/05 面试题
竞选班长自荐书范文
2014/03/09 职场文书
小学数学课题方案
2014/06/15 职场文书
2014年群众路线党员自我评议
2014/09/24 职场文书
四年级小学生评语
2014/12/26 职场文书
个人总结与自我评价2015
2015/03/11 职场文书
银行中层干部培训心得体会
2016/01/11 职场文书
用Python提取PDF表格的方法
2021/04/11 Python
win10双系统怎么删除一个系统?win10电脑有两个系统删除一个的操作方法
2022/07/15 数码科技