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. <styletype="text/css">
  5. #progress{
  6. border:2pxredsolid;
  7. width:200px;
  8. height:20px;
  9. display:none;
  10. }
  11. #pecent{
  12. background-color:green;
  13. display:block;
  14. width:0px;
  15. height:20px;
  16. color:yellow;
  17. }
  18. </style>
  19. </head>
  20. <body>
  21. <iframestyle="display:none"name="ifm"></iframe>
  22. <formenctype="multipart/form-data"method="POST"action="upload.php"target="ifm"name="myform">
  23. <inputtype="hidden"name="APC_UPLOAD_PROGRESS"id="remark">
  24. <inputtype="file"name="upfile"/>
  25. <inputtype="submit"value="上传"name="sub"/>
  26. </form>
  27. <divid="progress"class="before"><spanid="pecent"></span></div>
  28. <scripttype="text/javascript">
  29. (function(){
  30. functionaddEvent(node,type,listener){
  31. if(node.addEventListener){
  32. //W3Cmethod
  33. node.addEventListener(type,listener,false);
  34. returntrue;
  35. }elseif(node.attachEvent){
  36. //MSIEmethod
  37. node['e'+type+listener]=listener;
  38. node[type+listener]=function(){node['e'+type+listener](window.event);}
  39. node.attachEvent('on'+type,node[type+listener]);
  40. returntrue;
  41. }
  42. //Didn'thaveeithersoreturnfalse
  43. returnfalse;
  44. };
  45. varsubmit=document.forms["myform"];
  46. addEvent(submit,'submit',startUpload);
  47. varbegin;
  48. varrequest;
  49. varrdm;
  50. varpec=document.getElementById("pecent");
  51. functionstartUpload()
  52. {
  53. rdm=Math.floor(Math.random()*100000000);
  54. document.getElementById('remark').setAttribute('value',rdm);
  55. document.getElementById("progress").style['display']='block';
  56. //creatXmlHttpRequest();
  57. begin=setTimeout(doRequest,1000);
  58. };
  59. functioncreatXmlHttpRequest()
  60. {
  61. if(window.ActiveXObject)
  62. {request=newActiveXObject("Microsoft.XMLHTTP")}
  63. else{request=newXMLHttpRequest();}
  64. };
  65. varcount=0;
  66. functiondoRequest()
  67. {
  68. if(window.ActiveXObject)
  69. {request=newActiveXObject("Microsoft.XMLHTTP");}
  70. else{request=newXMLHttpRequest();}
  71. if(request!=null){
  72. request.onreadystatechange=handle;
  73. request.open("GET","upload.php?key="+rdm+"&sim="+(++count),true);
  74. request.send();
  75. }
  76. };
  77. functionhandle()
  78. {
  79. if(request.readyState==4&&request.status==200)
  80. {
  81. //接受服务器数据
  82. varprgs=eval("("+request.responseText+")");
  83. //varprgs=request.responseText;
  84. varcur=parseInt(prgs.current);
  85. vartotal=parseInt(prgs.total);
  86. varpecentIs=Math.round(cur/total*100);
  87. pec.innerHTML=pecentIs.toString()+"%";
  88. if(100==pecentIs)
  89. {
  90. pec.style['width']="200px";
  91. clearTimeout(begin);
  92. }else{
  93. begin=setTimeout(doRequest,1000);
  94. //alert(pecentIs);
  95. pec.style['width']=pecentIs*2;
  96. }
  97. }
  98. };
  99. })();
  100. </script>
  101. </body>
  102. </html>

2后台upload.php文件代码:

Php代码 收藏代码
  1. <?php
  2. /*
  3. *Createdon2010-4-16
  4. *
  5. *Tochangethetemplateforthisgeneratedfilegoto
  6. *Window-Preferences-PHPeclipse-PHP-CodeTemplates
  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. if(isset($_GET['key']))
  17. {
  18. //header('Content-Type:application/json;charset=utf-8');
  19. //RetrievethestatususingthegetStatus()functionbelow
  20. //echojson_encode(getStatusAPC());
  21. echojson_encode(getStatusAPC());
  22. }
  23. functiongetStatusAPC()
  24. {
  25. $response=false;
  26. if($status=apc_fetch('upload_'.$_GET['key'])){
  27. $response=apc_fetch('upload_'.$_GET['key']);
  28. }
  29. return$response;
  30. }
  31. ?>

问题总结:

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值