PHP基于session.upload_progress 实现文件上传进度显示功能详解


Posted in PHP onAugust 09, 2019

本文实例讲述了PHP基于session.upload_progress 实现文件上传进度显示功能。分享给大家供大家参考,具体如下:

介绍

session.upload_progress 是PHP5.4的新特征。

当 session.upload_progress.enabled INI 选项开启时,PHP 能够在每一个文件上传时监测上传进度。 这个信息对上传请求自身并没有什么帮助,但在文件上传时应用可以发送一个POST请求到终端(例如通过XHR)来检查这个状态。

当一个上传在处理中,同时POST一个与INI中设置的session.upload_progress.name同名变量时,上传进度可以在$_SESSION中获得。 当PHP检测到这种POST请求时,它会在$_SESSION中添加一组数据, 索引是session.upload_progress.prefix与 session.upload_progress.name连接在一起的值。

开启session.upload_progress

修改php.ini文件,开启session.upload_progress的支持。

session.upload_progress.enabled = On
session.upload_progress.cleanup = On
session.upload_progress.prefix = "upload_progress_"
session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS"
session.upload_progress.freq = "1%"
session.upload_progress.min_freq = "1"

对于PHP语言,这应该是最好的解决方案了,因为这种方式依赖于PHP内部的session机制,开始上传文件创建相关session以便读取,文件上传完成就会销毁session。html5的文件上传api也可以显示上传进度,但是对IE的10以下的版本没法使用,所以兼容性不太好。

接下来,我们通过一个例子,实现以下相关效果。

修改php上传文件限制

php.ini默认的上传文件大小上限为2M,然而我们既然需要显示文件上传进度,肯定都是要能够上传比较大的文件。尤其我们在本地服务器上测试的时候,因为服务器保存的路径是在本地磁盘上,所以文件上传就相当于在磁盘上复制,速度很快,我们想要比较直观的看到上传进度的显示,就需要上传一个比较大的文件,我在测试的时候,上传的是一个400多M的压缩包。

可以通过下面的php.ini的配置,调整上传文件大小的限制(以上限500M为例)

upload_max_filesize = 500M; //上传文件的最大值,还可以调更大
post_max_size = 500M;    //post方式传递过来数据最大值,还可以调更大
max_execution_time = 1800; //页面最大执行时间,已经设置为最大值
max_input_time = 1800; //解析传入数据最大执行时间,已经设置为最大值
memory_limit = 128M;  //每个页面消耗的最大内存,已经设置为最大值

实例程序

首先放上最简单的部分,上传文件转存程序

upload.php

<?php
if(isset($_FILES['demo'])){
  $tmp=explode(".",$_FILES['demo']['name']);
  $suffix_name = end($tmp);
  $name = time().".".$suffix_name;
  $path = __DIR__."\\".$name;
  move_uploaded_file($_FILES['demo']['tmp_name'],$path);
  echo "upload success";
}else{
  echo "error";
}

然后是前台获取上传文件百分数的接口文件

progress.php

<?php
session_start();
$key = ini_get("session.upload_progress.prefix") . $_GET["key"];
if (!empty($_SESSION[$key])) {
  $current = $_SESSION[$key]["bytes_processed"];
  $total = $_SESSION[$key]["content_length"];
  echo $current < $total ? ceil($current / $total * 100) : 100;
}else{
  echo 100;
}

最后是前台的上传文件界面

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>上传文件示例程序</title>
</head>
<body>
<div id="fileUpload">
  <form id="upload-form" action="upload.php" method="post" enctype="multipart/form-data" target="hidden_iframe">
    <p>
      <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="file1" />
      <input type="file" name="demo">
      <input type="submit" value="上传">
    </p>
  </form>
</div>
<iframe name="hidden_iframe" src="about:blank" style="display:none;"></iframe>
<div id="process">
  上传进度:<span id="percent"></span>
</div>
</body>
<script src="http://apps.bdimg.com/libs/jquery/1.6.4/jquery.min.js"></script>
<script>
  function fetch_progress(){
    $.get('progress.php',{"key":"file1"}, function(data){
      document.getElementById("percent").innerText = data+"%";
      if(data == 100){
        return;
      }else{
        setTimeout(fetch_progress,100);
      }
    });
  }
  $('#upload-form').submit(function(){
    setTimeout(fetch_progress,100);
  });
</script>
</html>

在前台页面,通过form的target属性,将提交之后的页面指向了该页的iframe,避免了页面的跳转。

总结

php.ini默认配置的上传文件大小是2M,我们上传文件通常是需要修改一下配置文件使用的。

从php5.4开始,通过php.ini配置session.upload_progress之后,文件上传时,就会创建key为session.upload_progress.prefix+session.upload_progress.name的session。其中session.upload_progress.prefix是配置文件中定义的,session.upload_progress.name需要在form表单提交时,一并提交才可以。

文件开始上传,创建session,上传过程中,session文件中保存了以上传字节数和总字节数,可以以及计算得到上传文件百分比,在上传完成之后,该session会被销毁。

bootstrap样式的进度条

index.html加上bootstrap的进度条样式,顿时高大上多了,哈哈

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>上传文件示例程序</title>
  <link rel="stylesheet" href="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/css/bootstrap.min.css" rel="external nofollow" >
  <script src="http://cdn.static.runoob.com/libs/jquery/2.1.1/jquery.min.js"></script>
  <script src="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div style="width: 400px;margin-top: 30px;margin-left: 30px;">
  <div id="fileUpload">
    <form class="form-horizontal" role="form" id="upload-form" action="upload.php" method="post" enctype="multipart/form-data" target="hidden_iframe">
      <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="file1" />
      <div class="form-group">
        <div class="col-sm-8" style="margin-top: 7px;">
          <input type="file" name="demo" >
        </div>
        <div class="col-sm-4">
          <button type="submit" class="btn btn-primary btn-sm">上传文件</button>
        </div>
      </div>
    </form>
  </div>
  <iframe name="hidden_iframe" src="about:blank" style="display:none;"></iframe>
  <div class="progress" style="display: none;">
    <div id="percent" class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width:0%;">
      0%
    </div>
  </div>
</div>
</body>
<script>
  function fetch_progress(){
    $.get('progress.php',{"key":"file1"}, function(data){
      document.getElementById("percent").innerText = data+"%";
      document.getElementById("percent").setAttribute("style","width:"+data+"%;");
      document.getElementsByClassName("progress")[0].setAttribute("style","display: block;");
      if(data == 100){
        return;
      }else{
        setTimeout(fetch_progress,100);
      }
    });
  }
  $('#upload-form').submit(function(){
    setTimeout(fetch_progress,100);
  });
</script>
</html>

显示效果

PHP基于session.upload_progress 实现文件上传进度显示功能详解

参考文档:

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
php ob_flush,flush在ie中缓冲无效的解决方法
May 09 PHP
解析:通过php socket并借助telnet实现简单的聊天程序
Jun 18 PHP
如何在Ubuntu下启动Apache的Rewrite功能
Jul 05 PHP
Yii的CDbCriteria查询条件用法实例
Dec 04 PHP
PHP文件上传之多文件上传的实现思路
Jan 27 PHP
Yii2中DropDownList简单用法示例
Jul 18 PHP
PHP输出图像imagegif、imagejpeg与imagepng函数用法分析
Nov 14 PHP
thinkPHP线上自动加载异常与修复方法实例分析
Dec 01 PHP
完美解决Thinkphp3.2中插入相同数据的问题
Aug 01 PHP
PHPExcel 修改已存在Excel的方法
May 03 PHP
CodeIgniter框架实现的整合Smarty引擎DEMO示例
Mar 28 PHP
laravel Task Scheduling(任务调度)在windows下的使用详解
Oct 22 PHP
PHP实现提高SESSION响应速度的几种方法详解
Aug 09 #PHP
php tpl模板引擎定义与使用示例
Aug 09 #PHP
php函数式编程简单示例
Aug 08 #PHP
因str_replace导致的注入问题总结
Aug 08 #PHP
PHP goto语句用法实例
Aug 06 #PHP
Laravel 6 将新增为指定队列任务设置中间件的功能
Aug 06 #PHP
Yii框架核心组件类实例详解
Aug 06 #PHP
You might like
PHP 文件上传源码分析(RFC1867)
2009/10/30 PHP
直接生成打开窗口代码,不必下载
2008/05/14 Javascript
javascript控制frame,iframe的src属性代码
2009/12/31 Javascript
JSONP 跨域访问代理API-yahooapis实现代码
2012/12/02 Javascript
script的async属性以非阻塞的模式加载脚本
2013/01/15 Javascript
js实现图片和链接文字同步切换特效的方法
2015/02/20 Javascript
javascript中字体浮动效果的简单实例演示
2015/11/18 Javascript
JavaScript实现时间倒计时跳转(推荐)
2016/06/28 Javascript
利用原生js和jQuery实现单选框的勾选和取消操作的方法
2016/09/04 Javascript
AngularJS自定义插件实现网站用户引导功能示例
2016/11/07 Javascript
Bootstrap表格制作代码
2017/03/17 Javascript
jQuery实现的两种简单弹窗效果示例
2018/04/18 jQuery
vue实现新闻展示页的步骤详解
2019/04/11 Javascript
了解在JavaScript中将值转换为字符串的5种方法
2019/06/06 Javascript
微信小程序中target和currentTarget的区别小结
2020/11/06 Javascript
js实现随机点名
2021/01/19 Javascript
[01:50]2014DOTA2西雅图邀请赛 专访欢乐周宝龙
2014/07/08 DOTA
python分析apache访问日志脚本分享
2015/02/26 Python
Windows下python2.7.8安装图文教程
2016/05/26 Python
用Python将IP地址在整型和字符串之间轻松转换
2017/03/22 Python
Python基于回溯法子集树模板解决全排列问题示例
2017/09/07 Python
Python随机生成均匀分布在单位圆内的点代码示例
2017/11/13 Python
python requests 测试代理ip是否生效
2018/07/25 Python
idea创建springMVC框架和配置小文件的教程图解
2018/09/18 Python
Python lambda表达式用法实例分析
2018/12/25 Python
python 实现Flask中返回图片流给前端展示
2020/01/09 Python
Python sklearn库实现PCA教程(以鸢尾花分类为例)
2020/02/24 Python
Dr. Martens马汀博士澳大利亚官网:马丁靴鼻祖
2019/07/02 全球购物
linux面试题参考答案(9)
2015/01/07 面试题
构建高效课堂实施方案
2014/03/13 职场文书
教师节促销方案
2014/03/22 职场文书
让世界充满爱演讲稿
2014/05/24 职场文书
2014年酒店工作总结与计划
2014/11/17 职场文书
如何制定一份可行的计划!
2019/06/21 职场文书
彩虹社八名人气艺人全新周边限时推出,性转女装男装一次拥有!
2022/04/01 日漫
Win10服务全部禁用了怎么启动?Win10服务全部禁用解决方法
2022/09/23 数码科技