PHP上传文件进度条的实现详情

今天研究了下PHP上传文件进度条的实现方法,从网上查到的资料,实现PHP上传文件进度条提示的方法主要有三种,这三种方法分别是:

1、使用PHP的创始人 Rasmus Lerdorf 写的APC扩展模块来实现(http://pecl.php.net/package/apc

2、使用PECL扩展模块 uploadprogress实现(http://pecl.php.net/package/uploadprogress

3、使用flash+PHP来实现。

这三种方法都是经过实验成功证明是可行的。

这里主要详细讨论第一种实现方法(第二种实现方法与第一种基本相同,第三种方法要求会actionScript).要求PHP版本5.2.0以上。

过程步骤:

第一步:让PHP支持apc扩展模块。若是在win下,则只要把php_apc.dll文件拷贝到PHP的安装目录下的ext文件夹中.然后修改php.ini文件,把

extension=php_apc.dll

apc.rfc1867 = on
apc.max_file_size = 1000M
upload_max_filesize = 1000M
post_max_size = 1000M

apc.max_file_size,  设置apc所支持上传文件的大小,要求apc.max_file_size <=upload_max_filesize  并且

apc.max_file_size <=post_max_size.

重新启动apache即可实现apc的支持.

若是在linux系统下,则需要从http://pecl.php.net/package/apc下载原代码进行编译。这里下载的是3.0.15版本。

解压 安装
/usr/local/php/bin/phpize
./configure --enable-apc --enable-apc-mmap --with-php-config=/usr/local/php/bin/php-config
make
make install
cp /usr/local/php/lib/php/extensions/no-debug-zts-20060613/apc.so /usr/local/php/lib/php/extensions/apc.so
chmod 755 /usr/local/php/lib/php/extensions/apc.so

配置/etc/php.ini 末尾加入
extension=apc.so
apc.enabled = 1
apc.cache_by_default = on
apc.shm_segments = 1
apc.shm_size = 32
apc.ttl = 600
apc.user_ttl = 600
apc.num_files_hint = 0
apc.write_lock = On
apc.max_file_size = 1000M
upload_max_filesize = 1000M
post_max_size = 1000M

这里要确认的一点:extension_dir是否是/usr/local/php/lib/php/extensions/,否则apc.so模块将无法加载进来。顺便解释下配置:

apc.cache_by_default = On
是否默认对所有文件启用缓冲。 若设为Off并与以加号开头的apc.filters指令一起用,则文件仅在匹配过滤器时才被缓存

apc.enabled = On
是否启用APC,如果APC被静态编译进PHP又想禁用它,这是唯一的办法。

 

apc.rfc1867 = on

此项设置使apc支持上传进度条


pc.filters =
一个以逗号分隔的POSIX扩展正则表达式列表。
如果源文件名与任意一个模式匹配,则该文件不被缓存。
注意,用来匹配的文件名是传递给include/require的文件名,而不是绝对路径。
如果正则表达式的第一个字符是"+"则意味着任何匹配表达式的文件会被缓存,如果第一个字符是"-"则任何匹配项都不会被缓存。"-"是默认值,可以省略掉。

apc.ttl = 0
缓存条目在缓冲区中允许逗留的秒数。0 表示永不超时。建议值为7200~36000。 设为 0 意味着缓冲区有可能被旧的缓存条目填满,从而导致无法缓存新条目。

apc.user_ttl = 0
类似于apc.ttl,只是针对每个用户而言,建议值为7200~36000。

apc.gc_ttl = 3600
缓存条目在垃圾回收表中能够存在的秒数
此值提供了一个安全措施,即使一个服务器进程在执行缓存的源文件时崩溃, 中.国.站长站
而且该源文件已经被修改,为旧版本分配的内存也不会被回收,直到达到此TTL值为止。设为零将禁用此特性。

pc.max_file_size = 1M
禁止大于此尺寸的文件被缓存。

apc.num_files_hint = 1000
Web服务器上可能被包含或被请求的不同源文件的大致数量(建议值为1024~4096)。
如果你不能确定,则设为 0 ;此设定主要用于拥有数千个源文件的站点。


apc.shm_segments = 1
为编译器缓冲区分配的共享内存块数量(建议值为1)。
如果APC耗尽了共享内存,并且已将apc.shm_size指令设为系统允许的最大值,你可以尝试增大此值。

apc.shm_size = 30
每个共享内存块的大小(以MB为单位,建议值为128~256)。
有些系统(包括大多数BSD变种)默认的共享内存块大小非常少。

apc.write_lock = On
是否启用写入锁。
在非常繁忙的服务器上,无论是启动服务还是修改文件,都可能由于多个进程企图同时缓存一个文件而导致竞争条件
启用该指令可以避免竞争条件的出现。

重新启动apache即可实现apc的支持.
测试是否成功支持apc的脚本:

check.php

<?php
if (function_exists('apc_fetch')) {
 echo 'it surpport apc model!';
}else {
    echo "it's not support apc model!";
}
?>

2、上传进度条实现文件(firefox/IE6.0/IE7.0  supported):

文件一、progress.php

<?php
   $id = md5(uniqid(rand(), true));
?>
<html>
<head><title>Upload Example</title></head>
<body>

<script language="javascript">

var xmlHttp;
var proNum=0;
var loop=0;

var Try = {
  these: function() {
    var returnValue;
    for (var i = 0; i < arguments.length; i++) {
      var lambda = arguments[i];
      try {
        returnValue = lambda();
        break;
      } catch (e) {}
    }
    return returnValue;
  }
}

function createXHR(){
 return Try.these(
      function() {return new XMLHttpRequest()},
      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
      function() {return new ActiveXObject('Microsoft.XMLHTTP')}
    ) || false;
}

var xmlHttp;

function sendURL() {
    xmlHttp=createXHR();
 var url="getprogress.php?progress_key=<?php echo $id;?>";
    xmlHttp.onreadystatechange = doHttpReadyStateChange;
    xmlHttp.open("GET",url,true);
    xmlHttp.send(null);  
}

function doHttpReadyStateChange() {
   if (xmlHttp.readyState == 4){
  proNum=parseInt(xmlHttp.responseText);
  document.getElementById("progressinner").style.width = proNum+"%";
  document.getElementById("showNum").innerHTML = proNum+"%";
  if ( proNum < 100){
   setTimeout("getProgress()", 100);
  }
 }
}

function getProgress(){
 loop++;
 document.getElementById("showNum2").innerHTML = loop;
 sendURL();
}
var interval;
function startProgress(){
    document.getElementById("progressouter").style.display="block";
    setTimeout("getProgress()", 100);
}

</script>

<iframe id="theframe" name="theframe"
        src="upload.php?id=<?php echo($id); ?>"
        style="border: none; height: 100px; width: 400px;" >
</iframe>
<br/><br/>

<div id="progressouter" style=
   "width: 500px; height: 20px; border: 6px solid red; display:none;">
   <div id="progressinner" style=
       "position: relative; height: 20px; background-color: purple; width: 0%; ">
   </div>
</div><div id='showNum'></div><br>
<div id='showNum2'></div>
</body>
</html>

文件二、upload.php

<?php
   $id = $_GET['id'];
?>

<form enctype="multipart/form-data" id="upload_form"
      action="target.php" method="POST">

<input type="hidden" name="APC_UPLOAD_PROGRESS"
       id="progress_key"  value="<?php echo $id?>"/>

<input type="file" id="test_file" name="test_file"/><br/>

<input οnclick="window.parent.startProgress(); return true;"
 type="submit" value="Upload!"/>

</form>

文件三、target.php

<?php 
set_time_limit(600);
if($_SERVER['REQUEST_METHOD']=='POST') {
  move_uploaded_file($_FILES["test_file"]["tmp_name"],
  dirname($_SERVER['SCRIPT_FILENAME'])."/UploadTemp/" . $_FILES["test_file"]["name"]);//UploadTemp文件夹位于此脚本相同目录下
  echo "<p>File uploaded.  Thank you!</p>";
}

?>

文件四、getprogress.php

<?php
session_start();
if(isset($_GET['progress_key'])) {
  $status = apc_fetch('upload_'.$_GET['progress_key']);
  echo ($status['current']/$status['total'])*100;
}
?>

完毕。顺便付上相应附件,下载地址
http://download.csdn.net/user/fafa211/

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值