PHP APC扩展模块实现大文件上传

上周需要完成PHP大文件的上传,并且还要带AJAX进度条,于是在网上搜了下,决定使用PHP的创始人 Rasmus Lerdorf 写的APC扩展模块来实现(http://pecl.php.net/package/apc )。

一. APC模块的安装与配置

我的环境是Windows,需要去下载php_apc. dll文件,并把php_apc.dll放到php/ext中,并在php.ini中添加以下语句:

extension = php_apc.dll

apc.rfc1867 = 1

apc.max_file_size = 200M

另外,由于需要上传大文件,所以,在php.ini中,以下选项也需要更改:

upload_max_filesize = 1000M

post_max_size = 1000M

max_execution_time = 600 ;每个PHP页面运行的最大时间值(秒),默认30秒

max_input_time = 600 ;每个PHP页面接收数据所需的最大时间,默认60秒

memory_limit = 128M ;每个PHP页面所吃掉的最大内存,默认8M

二. 获取进度条代码

getprogress.php

 

<?php session_start(); if(isset($_GET['progress_key'])) { $status = apc_fetch('upload_'.$_GET['progress_key']); if($status['total']!=0 && !empty($status['total'])) { echo json_encode($status); } else { echo (0); } } ?>

 

这里用到了json,传数据非常方便。

$status对象是拥有以下字段的数组:

total: 文件总大小

current: 到目前为止收到的文件数

rate: 上传速度(以字节/秒为单位),不过要在上传完成之后才能有。

filename: 文件名

name: 变量名

temp_filename: PHP 保存文件的临时副本的位置

cancel_upload: 上传已取消(1),还是未取消(0)

done: 上传已完成(1),还是尚未完成(0)

这里,我们用json全部传到页面,方便后面利用。

三. 主文件

upload.php

 

<?php $id = md5(uniqid(rand(), true)); ?> <html> <head> <title>Upload Example</title> </head> <body> <mce:script language="javascript"><!-- var xmlHttp; var json_current; var json_total; var percent; var loop = 0; var last = 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) { // status为getprogress中json_encode传过来的 var status = xmlHttp.responseText; // 解析status,这样,获取对象就可以用json.something获得 var json = eval("(" + status + ")"); json_current = parseInt(json.current); json_total = parseInt(json.total); precent = parseInt(json_current/json_total * 100); document.getElementById("progressinner").style.width = precent+"%"; document.getElementById("showNum").innerHTML = precent+"%"; document.getElementById("showInfo").innerHTML = status; if ( precent < 100) { setTimeout("getProgress()", 100); } } } function getProgress() { sendURL(); } var interval; function startProgress() { document.getElementById("progressouter").style.display="block"; setTimeout("getProgress()", 100); } // --></mce:script> <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="upload_file" name="upload_file" /><br/> <input onclick="window.startProgress(); return true;" type="submit" value="Upload!" /> </form> <div id="progressouter" style= "width: 500px; height: 20px; border: 1px solid black; display:none;"> <div id="progressinner" style= "position: relative; height: 20px; background-color: gray; width: 0%; "> </div> </div> <br /> <div id='showNum'></div><br> <div id='showInfo'></div><br> </body> </html>

 

这里,下面的代码将刚刚收到的json字符串还原出来:

 

// 解析status,这样,获取对象就可以用json.something获得 var json = eval("(" + status + ")"); json_current = parseInt(json.current); json_total = parseInt(json.total);

 

四. 上传文件的接收与保存

target.php

 

<?php 
set_time_limit(600);
if($_SERVER['REQUEST_METHOD'] == 'POST') {
    move_uploaded_file($_FILES["upload_file"]["tmp_name"],
    dirname($_SERVER['SCRIPT_FILENAME'])."/UploadFiles/".$_FILES["upload_file"]["name"]);
    echo "<p>File uploaded.</p>";
}
?>

你可能感兴趣的:(PHP APC扩展模块实现大文件上传)