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 相关文章推荐
php递归使用示例(php递归函数)
Feb 14 PHP
PHP基于数组实现的分页函数实例
Aug 20 PHP
PHP经典算法集锦【经典收藏】
Sep 14 PHP
php实现当前页面点击下载文件的简单方法
Sep 22 PHP
php与c 实现按行读取文件实例代码
Jan 03 PHP
PHP微信PC二维码登陆的实现思路
Jul 13 PHP
PHP基于堆栈实现的高级计算器功能示例
Sep 15 PHP
PHP实现的防止跨站和xss攻击代码【来自阿里云】
Jan 29 PHP
PHP之认识(二)关于Traits的用法详解
Apr 11 PHP
Laravel实现ApiToken认证请求
Oct 14 PHP
浅谈laravel框架sql中groupBy之后排序的问题
Oct 17 PHP
基于Laravel 多个中间件的执行顺序详解
Oct 21 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
有关PHP中MVC的开发经验分享
2012/05/17 PHP
phpphp图片采集后按原路径保存图片示例
2014/02/18 PHP
PHP输出英文时间日期的安全方法(RFC 1123格式)
2014/06/13 PHP
ThinkPHP框架任意代码执行漏洞的利用及其修复方法
2014/07/04 PHP
10个实用的脚本代码工具
2010/05/04 Javascript
把input初始值不写value的具体实现方法
2013/07/04 Javascript
使用闭包对setTimeout进行简单封装避免出错
2013/07/10 Javascript
js写的评论分页(还不错)
2013/12/23 Javascript
JS动态添加Table的TR,TD实现方法
2015/01/28 Javascript
jQuery实现带动画效果的二级下拉导航方法
2015/03/11 Javascript
jQuery模拟select实现下拉菜单功能
2016/06/20 Javascript
JavaScript判断浏览器对CSS3属性是否支持的多种方法
2016/11/13 Javascript
浅谈js script标签中的预解析
2016/12/30 Javascript
JavaScript轻松创建级联函数的方法示例
2017/02/10 Javascript
微信小程序page的生命周期和音频播放及监听实例详解
2017/04/07 Javascript
vue之数据交互实例代码
2017/06/20 Javascript
微信小程序中页面FOR循环和嵌套循环
2017/06/21 Javascript
vue-cli3脚手架的配置及使用教程
2018/08/28 Javascript
解决vue+ element ui 表单验证有值但验证失败问题
2020/01/16 Javascript
python字符串对其居中显示的方法
2015/07/11 Python
python中input()与raw_input()的区别分析
2016/02/27 Python
Python的Flask框架应用程序实现使用QQ账号登录的方法
2016/06/07 Python
Python操作MongoDB详解及实例
2017/05/18 Python
Sanic框架Cookies操作示例
2018/07/17 Python
python在openstreetmap地图上绘制路线图的实现
2019/07/11 Python
django用户登录验证的完整示例代码
2019/07/21 Python
Python-numpy实现灰度图像的分块和合并方式
2020/01/09 Python
Tensorflow 1.0之后模型文件、权重数值的读取方式
2020/02/12 Python
PyCharm设置注释字体颜色以及是否倾斜的操作
2020/09/16 Python
查询优化的一般准则有哪些
2015/03/08 面试题
大学生入党自我鉴定
2013/10/31 职场文书
工程测量与监理专业应届生求职信
2013/11/27 职场文书
2014年综治宣传月活动总结
2014/04/28 职场文书
世界遗产的导游词
2015/02/13 职场文书
经典爱情感言
2015/08/03 职场文书
QT连接MYSQL数据库的详细步骤
2021/07/07 MySQL