ajax和php登录进度条,PHP基于session+ajax实现文件上传进度条

一、场景及方案介绍

Web 应用中常常需要提供文件上传功能,典型的应用场景有用户头像、相册照片上传等。当要上传的文件比较大的时候,为了更好的用户体验,显示文件上传进度是必要。

在 PHP5.4 之前,php 实现文件上传进度条,主要有三种方法:

使用 flash、java、activeX

使用 PHP 的 APC 扩展

使用 HTML5 的 FILE API

第一种方法依赖第三方的浏览器插件,通用性不好,并且存在安全隐患。不过由于 flash 的使用范围较广,因此很多网站使用 flash 作为解决方案。

第二种方法不足在于需要安装 PHP 的 PAC 扩展库,要求用户能够控制服务器的配置。

第三中方法应该是最理想的方法,不需要服务器的支持,仅仅在浏览器使用 JavaScript 即可。但由于 HTML5 标准尚未完全确立,各个浏览器的支持不同,所以这种方法不能大规模使用。

在 PHP5.4 版本中引入基于 session 的上传进度监视功能(session.upload.progress),是一种服务器端文件上传进度解决方案。可以不用安装 APC 扩展,使用原生的 PHP 加 ajax 即可实现上传进度条。这里使用的是 session+jQuery ajax 实现。

二、原理介绍

当浏览器向服务器上传一个文件时,PHP 会吧此文件上传的详细信息(上传时间、进度)存储在 session 中。跟随上传的进行,周期的更新 session 中的信息。浏览器可以使用 ajax 周期的请求服务器端脚本,取得 session 中的进度信息,从而客户端显示进度条。

文件上传信息要存储在 session 中,需要在 php.ini 的配置文件中进行以下设置:

1

2

3

4

5

6

7

8

9

10

11

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”

其中,enabled 控制 upload_progress 功能开启与关闭,默认开启;cleanup 设置当文件上传请求提交完成后,是否清除 session 相关信息,默认开启;prefix 和 name 分别设置进度信息在 session 中存储的变量名和键名;freq 和 min_freq,两项用来设置服务器对进度的更新频率。合理的配置可以减轻服务器的负载。

另外在文件上传表单中,需要为该上传设置一个标识符,并在接下来的过程中使用该标识符来引用进度信息。具体操作,在上传表单中添加一个隐藏域,它的 name 属性为 php.ini 中的 session.upload_progress.name 的值。该隐藏域的值是一个你自己定义的标识符,代码如下:

1

2

value=”test” />

接着文件上传的表单后,PHP 会在 $_SESSION 变量中新建键,键名是一个将 session.upload_progress.prifix 的值与上面你所定义的标识符连接后的字符串,可以通过以下代码得到:

1

2

3

$i = ini_get(‘session.upload_progress.name’);

$key = ini_get(‘session.upload_progress.prefix’).$_POST[$i];

$_SESSION[$key];

SESSION[SESSION[key] 的变量结构如下:

1

2

3

4

5

6

7

8

9

10

$_SESSION[‘upload_progress_test’] = array(

“start_time” => 1234567890, //开始时间

“content_length” => 57343257, //POST请求的总数据长度

“bytes_processed” => 453489, //已收到的数据长度

“done” => false, //请求是否完成,true表示完成,false表示未完成

“files” => array( //文件信息

0 => array(…),

1 => array(…), //同一请求中包含多个文件

),

);

通过 $_SEESION 中的 conten_length 和 bytes_processed 可以求出文件上传百分比。

三、具体实现

index.php 表单内容如下:(注意在文件最前面使用 session_start() 开启 session)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

此处表单中 session.upload_progress.name 隐藏域的值设为了 test。表单中可以添加多个文件上传表单,如果需要的话。还有就是,表单的 target 属性,指向了当前页面的一个隐藏 iframe,作用是防止提交表单后页面跳转。

id 为 progress 这个 div 是用来你显示进度条的。

处理文件上传的文件时 upload.php,与通常文件上传操作没有什么不同:

1

2

3

4

if (is_uploaded_file($_FILES['file1']['tmp_name'])) {

move_uploaded_file($_FILES['file1']['tmp_name'], "./{ $_FILES['file1']['name'] }");

}

使用 ajax 获取进度信息:这是最为关键的一步,需要建立 progress.php 文件,读取 session 中的信息;然后在 index.php 增加 js 代码,向 progress.php 发起 ajax 请求,根据获取的进度信息更新进度条。progress.php 的代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

session_start();

$i = ini_get('session.upload_progress.name');

$key = ini_get('session.upload_progress.prefix') . $_GET[$i];

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.php 中加入如下 js 代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

$(function(){

function (){

$.get('progress.php', { '<?php echo ini_get("session.upload_progress.name");?>': 'test'}, function(data){

var progress = parseInt(data);

$('.handle').show().css('left', 2 * progress + 'px');

$('.label').html(progress + '%');

$('#progress .bar').css('width', 2 * progress + 'px');

if (progress < 100) {

setTimeout('fetch_progress()', 1);

} else {

$('.label').html('上传完成');

}

});

}

$('#upload-form').submit(function(){

$('#progress').show();

setTimeout('fetch_progress()', 1);

});

});

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值