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和ACCESS写聊天室(十)
Oct 09 PHP
据说是雅虎的一份PHP面试题附答案
Jan 07 PHP
ThinkPHP 防止表单重复提交的方法
Aug 08 PHP
探讨PHP函数ip2long转换IP时数值太大产生负数的解决方法
Jun 06 PHP
使用php实现快钱支付功能(涉及到接口)
Jul 01 PHP
解析PHP实现下载文件的两种方法
Jul 05 PHP
php中spl_autoload详解
Oct 17 PHP
PHP学习笔记(二):变量详解
Apr 17 PHP
PHP rsa加密解密使用方法
Apr 27 PHP
PHP编程获取音频文件时长的方法【基于getid3类】
Apr 20 PHP
ThinkPHP框架获取最后一次执行SQL语句及变量调试简单操作示例
Jun 13 PHP
laravel框架模型中非静态方法也能静态调用的原理分析
Nov 23 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
Yii中创建自己的Widget实例
2016/01/05 PHP
php插件Xajax使用方法详解
2017/08/31 PHP
JavaScript While 循环基础教程
2007/04/05 Javascript
JavaScript CSS修改学习第六章 拖拽
2010/02/19 Javascript
javascript中eval函数用法分析
2015/04/25 Javascript
简介JavaScript中Math.LOG10E属性的使用
2015/06/14 Javascript
node.js操作mysql(增删改查)
2015/07/24 Javascript
JavaScript 2048 游戏实例代码(简单易懂)
2016/03/25 Javascript
大型JavaScript应用程序架构设计模式
2016/06/29 Javascript
AngularJs  Creating Services详解及示例代码
2016/09/02 Javascript
通过AngularJS实现图片上传及缩略图展示示例
2017/01/03 Javascript
VueJs路由跳转——vue-router的使用详解
2017/01/10 Javascript
基于jQuery实现咖啡订单管理简单应用
2017/02/10 Javascript
vue服务端渲染的实例代码
2017/08/28 Javascript
Node.JS 循环递归复制文件夹目录及其子文件夹下的所有文件
2017/09/18 Javascript
javascript 缓冲运动框架的实现
2017/09/29 Javascript
Vue项目全局配置微信分享思路详解
2018/05/04 Javascript
浅谈JS对象添加getter与setter的5种方法
2018/06/09 Javascript
使用Easyui实现查询条件的后端传递并自动刷新表格的两种方法
2019/09/09 Javascript
layui 实现加载动画以及非真实加载进度的方法
2019/09/23 Javascript
Python tempfile模块学习笔记(临时文件)
2014/05/25 Python
Python实现八皇后问题示例代码
2018/12/09 Python
解决python多行注释引发缩进错误的问题
2019/08/23 Python
python实现最大优先队列
2019/08/29 Python
python集合的创建、添加及删除操作示例
2019/10/08 Python
Tensorflow卷积实现原理+手写python代码实现卷积教程
2020/05/22 Python
Python基于pillow库实现生成图片水印
2020/09/14 Python
python如何快速拼接字符串
2020/10/28 Python
python反编译教程之2048小游戏实例
2021/03/03 Python
基于CSS3的CSS 多栏(Multi-column)实现瀑布流源码分享
2014/06/11 HTML / CSS
草莓网美国官网:Strawberrynet USA
2016/12/11 全球购物
金融行业务员的自我评价
2013/12/13 职场文书
项目投资意向书
2014/04/01 职场文书
大学毕业生求职自荐书
2014/06/05 职场文书
Nginx本地目录映射实现代码实例
2021/03/31 Servers
Win11如何修改dns?Win11修改dns图文教程
2022/01/18 数码科技