php上传带进度

在PHP5.4以前, 我们可以通过APC提供的功能来实现. 或者使用PECL扩展uploadprogress来实现.


虽然说, 它们能很好的解决现在的问题, 但是也有很明显的不足:


1. 他们都需要额外安装(我们并没有打算把APC加入PHP5.4)
2. 它们都使用本地机制来存储这些信息, APC使用共享内存, 而uploadprogress使用文件系统(不考虑NFS), 这在多台前端机的时候会造成麻烦.






程序需要php的apc模块的支持,关键点就是在上传的form里添加一个hidden的inpu标签,里面要有name为
APC_UPLOAD_PROGRESS的属性,value值为一个随机数一遍多个人上传。
 
apc模块的安装方法是,下载php_apc.dll放到ext文件夹下,在php.ini文件里添加
upload_max_filesize =100M
      apc.rfc1867 = on
      apc.max_file_size = 100M
extension=php_apc.dll
然后测试配置是否成功:
if(apc_fetch)
{echo "apc is working"}
else{echo "apc is not supported!";}
 
 
 
运行效果截图


下面是源码
1 前台页面:
<html>  
<title>PHP+Ajax带进度条文件上传</title>  
<head>  
<style type="text/css">  
#progress{  
border:2px red solid;  
width:200px;  
height:20px;  
display:none;  
}  
  
#pecent{  
background-color:green;  
display:block;  
width:0px;  
height:20px;  
color:yellow;  
}  
</style>  
</head>  
<body>  
    <iframe style="display:none" name="ifm"></iframe>  
      <form enctype="multipart/form-data" method="POST" action="upload.php" target="ifm" name="myform">  
      <input type="hidden" name="APC_UPLOAD_PROGRESS" id="remark" >  
      <input type="file" name="upfile"/>  
      <input type="submit" value="上传" name="sub"/>  
      </form>  
      <div id="progress" class="before"><span id="pecent"></span></div>  
  
<script type="text/javascript">  
(function(){  
    function addEvent( node, type, listener ) {  
    if (node.addEventListener) {  
        // W3C method  
        node.addEventListener( type, listener, false );  
        return true;  
    } else if(node.attachEvent) {  
        // MSIE method  
        node['e'+type+listener] = listener;  
        node[type+listener] = function(){node['e'+type+listener]( window.event );}  
        node.attachEvent( 'on'+type, node[type+listener] );  
        return true;  
    }  
    // Didn't have either so return false  
    return false;  
    };  
    var submit=document.forms["myform"];  
    addEvent(submit,'submit',startUpload);  
    var begin;  
    var request;  
    var rdm;  
    var pec=document.getElementById("pecent");  
    function startUpload()  
    {  
        rdm=Math.floor(Math.random()*100000000);  
        document.getElementById('remark').setAttribute('value',rdm);  
        document.getElementById("progress").style['display']='block';  
        //creatXmlHttpRequest();  
        begin=setTimeout(doRequest,1000);  
    };  
    function creatXmlHttpRequest()  
    {  
        if(window.ActiveXObject)  
        {request=new ActiveXObject("Microsoft.XMLHTTP")}  
        else{request=new XMLHttpRequest();}  
    };  
    var count=0;  
    function doRequest()  
   {  
       if(window.ActiveXObject)  
        {request=new ActiveXObject("Microsoft.XMLHTTP");}  
        else{request=new XMLHttpRequest();}  
  
       if(request!=null){  
       request.onreadystatechange=handle;  
       request.open("GET","upload.php?key="+rdm+"&sim=" + (++count),true);  
       request.send();  
       }  
   };  
        function handle()  
        {  
            if(request.readyState==4&&request.status==200)  
            {  
                //接受服务器数据  
                var prgs=eval("(" +  request.responseText + ")");  
                //var prgs=request.responseText;  
                var cur=parseInt(prgs.current);  
                var total=parseInt(prgs.total);  
                var pecentIs=Math.round(cur/total*100);  
                pec.innerHTML=pecentIs.toString()+"%";  
                if(100==pecentIs)  
                {  
                    pec.style['width']="200px";  
                    clearTimeout(begin);  
                }else{  
                    begin=setTimeout(doRequest,1000);  
                    //alert(pecentIs);  
                    pec.style['width']=pecentIs*2;  
                }  
            }  
        };  
    })();  
    </script>  
    </body>  
</html>  
 
2后台upload.php文件代码:
<?php  
/* 
 * Created on 2010-4-16 
 * 
 * To change the template for this generated file go to 
 * Window - Preferences - PHPeclipse - PHP - Code Templates 
 */  
 if ($_SERVER['REQUEST_METHOD'] == 'POST'){  
$myfile=$_FILES['upfile'];  
echo $myfile['size'];  
echo $myfile['size'];  
print_r($myfile);  
$tempf=$myfile['tmp_name'];  
$name=$myfile['name'];  
move_uploaded_file($tempf,'up/'.$name);}  
  
if(isset($_GET['key']))  
{  
    //header('Content-Type:application/json; charset=utf-8' ) ;  
    // Retrieve the status using the getStatus() function below  
    //echo json_encode(getStatusAPC());  
    echo json_encode(getStatusAPC());  
}  
function getStatusAPC()  
{  
    $response=false;  
    if($status = apc_fetch('upload_'.$_GET['key'])) {  
          
        $response=apc_fetch('upload_'.$_GET['key']);  
          
    }  
    return $response;  
}  
  
?>  
 问题总结:
1,使用setTimeout嵌套和setInterval有区别,用前者效果较好,用后者的话由于请求和返回的时间比较随机,时间间隔把握不好的话,程序会比较混乱,结果往往不正确。
2.发送Ajax请求时每次都要重新实例化xmlhttprequest对象而不能用上次实例化的,否则程序在ie下无法执行,在火狐下可以运行
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值