今天研究了下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/