zoukankan      html  css  js  c++  java
  • 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代码  收藏代码
    1. <html>  
    2. <title>PHP+Ajax带进度条文件上传</title>  
    3. <head>  
    4. <style type="text/css">  
    5. #progress{  
    6. border:2px red solid;  
    7. 200px;  
    8. height:20px;  
    9. display:none;  
    10. }  
    11.   
    12. #pecent{  
    13. background-color:green;  
    14. display:block;  
    15. 0px;  
    16. height:20px;  
    17. color:yellow;  
    18. }  
    19. </style>  
    20. </head>  
    21. <body>  
    22.     <iframe style="display:none" name="ifm"></iframe>  
    23.       <form enctype="multipart/form-data" method="POST" action="upload.php" target="ifm" name="myform">  
    24.       <input type="hidden" name="APC_UPLOAD_PROGRESS" id="remark" >  
    25.       <input type="file" name="upfile"/>  
    26.       <input type="submit" value="上传" name="sub"/>  
    27.       </form>  
    28.       <div id="progress" class="before"><span id="pecent"></span></div>  
    29.   
    30. <script type="text/javascript">  
    31. (function(){  
    32.     function addEvent( node, type, listener ) {  
    33.     if (node.addEventListener) {  
    34.         // W3C method  
    35.         node.addEventListener( type, listener, false );  
    36.         return true;  
    37.     } else if(node.attachEvent) {  
    38.         // MSIE method  
    39.         node['e'+type+listener] = listener;  
    40.         node[type+listener] = function(){node['e'+type+listener]( window.event );}  
    41.         node.attachEvent( 'on'+type, node[type+listener] );  
    42.         return true;  
    43.     }  
    44.     // Didn't have either so return false  
    45.     return false;  
    46.     };  
    47.     var submit=document.forms["myform"];  
    48.     addEvent(submit,'submit',startUpload);  
    49.     var begin;  
    50.     var request;  
    51.     var rdm;  
    52.     var pec=document.getElementById("pecent");  
    53.     function startUpload()  
    54.     {  
    55.         rdm=Math.floor(Math.random()*100000000);  
    56.         document.getElementById('remark').setAttribute('value',rdm);  
    57.         document.getElementById("progress").style['display']='block';  
    58.         //creatXmlHttpRequest();  
    59.         begin=setTimeout(doRequest,1000);  
    60.     };  
    61.     function creatXmlHttpRequest()  
    62.     {  
    63.         if(window.ActiveXObject)  
    64.         {request=new ActiveXObject("Microsoft.XMLHTTP")}  
    65.         else{request=new XMLHttpRequest();}  
    66.     };  
    67.     var count=0;  
    68.     function doRequest()  
    69.    {  
    70.        if(window.ActiveXObject)  
    71.         {request=new ActiveXObject("Microsoft.XMLHTTP");}  
    72.         else{request=new XMLHttpRequest();}  
    73.   
    74.        if(request!=null){  
    75.        request.onreadystatechange=handle;  
    76.        request.open("GET","upload.php?key="+rdm+"&sim=" + (++count),true);  
    77.        request.send();  
    78.        }  
    79.    };  
    80.         function handle()  
    81.         {  
    82.             if(request.readyState==4&&request.status==200)  
    83.             {  
    84.                 //接受服务器数据  
    85.                 var prgs=eval("(" +  request.responseText + ")");  
    86.                 //var prgs=request.responseText;  
    87.                 var cur=parseInt(prgs.current);  
    88.                 var total=parseInt(prgs.total);  
    89.                 var pecentIs=Math.round(cur/total*100);  
    90.                 pec.innerHTML=pecentIs.toString()+"%";  
    91.                 if(100==pecentIs)  
    92.                 {  
    93.                     pec.style['width']="200px";  
    94.                     clearTimeout(begin);  
    95.                 }else{  
    96.                     begin=setTimeout(doRequest,1000);  
    97.                     //alert(pecentIs);  
    98.                     pec.style['width']=pecentIs*2;  
    99.                 }  
    100.             }  
    101.         };  
    102.     })();  
    103.     </script>  
    104.     </body>  
    105. </html>  

     

    2后台upload.php文件代码:

    Php代码  收藏代码
    1. <?php  
    2. /* 
    3.  * Created on 2010-4-16 
    4.  * 
    5.  * To change the template for this generated file go to 
    6.  * Window - Preferences - PHPeclipse - PHP - Code Templates 
    7.  */  
    8.  if ($_SERVER['REQUEST_METHOD'] == 'POST'){  
    9. $myfile=$_FILES['upfile'];  
    10. echo $myfile['size'];  
    11. echo $myfile['size'];  
    12. print_r($myfile);  
    13. $tempf=$myfile['tmp_name'];  
    14. $name=$myfile['name'];  
    15. move_uploaded_file($tempf,'up/'.$name);}  
    16.   
    17. if(isset($_GET['key']))  
    18. {  
    19.     //header('Content-Type:application/json; charset=utf-8' ) ;  
    20.     // Retrieve the status using the getStatus() function below  
    21.     //echo json_encode(getStatusAPC());  
    22.     echo json_encode(getStatusAPC());  
    23. }  
    24. function getStatusAPC()  
    25. {  
    26.     $response=false;  
    27.     if($status = apc_fetch('upload_'.$_GET['key'])) {  
    28.           
    29.         $response=apc_fetch('upload_'.$_GET['key']);  
    30.           
    31.     }  
    32.     return $response;  
    33. }  
    34.   
    35. ?>  

     问题总结:

    1,使用setTimeout嵌套和setInterval有区别,用前者效果较好,用后者的话由于请求和返回的时间比较随机,时间间隔把握不好的话,程序会比较混乱,结果往往不正确。

    2.发送Ajax请求时每次都要重新实例化xmlhttprequest对象而不能用上次实例化的,否则程序在ie下无法执行,在火狐下可以运行

     

  • 相关阅读:
    布局重用 include merge ViewStub
    AS 常用插件 MD
    AS 2.0新功能 Instant Run
    AS .ignore插件 忽略文件
    AS Gradle构建工具与Android plugin插件【大全】
    如何开通www国际域名个人网站
    倒计时实现方案总结 Timer Handler
    AS 进行单元测试
    RxJava 设计理念 观察者模式 Observable lambdas MD
    retrofit okhttp RxJava bk Gson Lambda 综合示例【配置】
  • 原文地址:https://www.cnblogs.com/y0umer/p/2809614.html
Copyright © 2011-2022 走看看