php文件打包 下载之使用PHP自带的ZipArchive压缩文件并下载打包好的文件


Posted in PHP onJune 13, 2012

总结:

 

使用PHP下载文件的操作需要给出四个header(),可以参考我的另一篇博文:PHP如何实现下载功能超详细流程分析
计算文件的大小的时候,并不需要先打开文件,通过filesize($filename)就可以看出,如果需要先打开文件的话,filesize可能就会是这样的形式了filesize($filehandle)
向客户端回送数据的是,记得要设置一个buffer,用来指定每次向客户端输出多少数据,如:$buffer=1023。如果不指定的话,就会将整个文件全部写入内存当中,再一次性的讲数据传送给客户端
通过feof()函数,可以判断要读取的文件是否读完,如果还没读完,继续读取文件($file_data=fread()),并将数据回送给客户端(echo $file_data)
每次下载完成后,在客户端都会刷新下,说明了,其实每次都将数据写入到一个临时文件中,等全部下载完成后,再将所有的数据重新整合在一起
这里我使用的是绝对路径,绝对路径有个好处,就是适应性比较强,而且相对于相对路径,效率更高(免去了查找文件的过程)
分析下技术要点:

将文件打包成zip格式

下载文件的功能

要点解析:

这里我采用的是php自带的ZipArchive类

a) 我们只需要new一个ZipArchive对象,然后使用open方法创建一个zip文件,接着使用addFile方法,将要打包的文件写入刚刚创建的zip文件中,最好还得记得关闭该对象。

b) 注意点:使用open方法的时候,第二个参数$flags是可选的,$flags用来指定对打开的zip文件的处理方式,共有四种情况

  i. ZIPARCHIVE::OVERWRITE 总是创建一个新的文件,如果指定的zip文件存在,则会覆盖掉

ii. ZIPARCHIVE::CREATE 如果指定的zip文件不存在,则新建一个

iii. ZIPARCHIVE::EXCL 如果指定的zip文件存在,则会报错

iv. ZIPARCHIVE::CHECKCONS

下载文件的流程:

 

服务器端的工作:

客户端的浏览器发送一个请求到处理下载的php文件。
注意:任何一个操作都首先需要写入到内存当中,不管是视频、音频还是文本文件,都需要先写入到内存当中。
换句话说,将“服务器”上的文件读入到“服务器”的内存当中的这个操作时必不可少的(注意:这里我将服务器三个字加上双引号,主要是说明这一系类的操作时在服务器上完成的)。<br>
既然要将文件写入到内存当中,就必然要先将文件打开
所以这里就需要三个文件操作的函数了:
一:fopen($filename ,$mode)
二:fread ( int $handle , int $length )
三:fclose ( resource $handle )

客户端端的工作:

那么,如何将已经存在于服务器端内存当中的文件信息流,传给客户端呢?
答案是通过header()函数,客户端就知道该如何处理文件,是保存还是打开等等

最终的效果如下图所示:

php文件打包 下载之使用PHP自带的ZipArchive压缩文件并下载打包好的文件

<?php 
require'./download.php'; 
/** 
* 遍历目录,打包成zip格式 
*/ 
class traverseDir{ 
public $currentdir;//当前目录 
public $filename;//文件名 
public $fileinfo;//用于保存当前目录下的所有文件名和目录名以及文件大小 
public function __construct(){ 
$this->currentdir=getcwd();//返回当前目录 
} 
//遍历目录 
public function scandir($filepath){ 
if (is_dir($filepath)){ 
$arr=scandir($filepath); 
foreach ($arr as $k=>$v){ 
$this->fileinfo[$v][]=$this->getfilesize($v); 
} 
}else { 
echo "<script>alert('当前目录不是有效目录');</script>"; 
} 
} 
/** 
* 返回文件的大小 
* 
* @param string $filename 文件名 
* @return 文件大小(KB) 
*/ 
public function getfilesize($fname){ 
return filesize($fname)/1024; 
} 
/** 
* 压缩文件(zip格式) 
*/ 
public function tozip($items){ 
$zip=new ZipArchive(); 
$zipname=date('YmdHis',time()); 
if (!file_exists($zipname)){ 
$zip->open($zipname.'.zip',ZipArchive::OVERWRITE);//创建一个空的zip文件 
for ($i=0;$i<count($items);$i++){ 
$zip->addFile($this->currentdir.'/'.$items[$i],$items[$i]); 
} 
$zip->close(); 
$dw=new download($zipname.'.zip'); //下载文件 
$dw->getfiles(); 
unlink($zipname.'.zip'); //下载完成后要进行删除 
} 
} 
} 
?>

<?php 
/** 
* 下载文件 
* 
*/ 
class download{ 
protected $_filename; 
protected $_filepath; 
protected $_filesize;//文件大小 
public function __construct($filename){ 
$this->_filename=$filename; 
$this->_filepath=dirname(__FILE__).'/'.$filename; 
} 
//获取文件名 
public function getfilename(){ 
return $this->_filename; 
} //获取文件路径(包含文件名) 
public function getfilepath(){ 
return $this->_filepath; 
} 
//获取文件大小 
public function getfilesize(){ 
return $this->_filesize=number_format(filesize($this->_filepath)/(1024*1024),2);//去小数点后两位 
} 
//下载文件的功能 
public function getfiles(){ 
//检查文件是否存在 
if (file_exists($this->_filepath)){ 
//打开文件 
$file = fopen($this->_filepath,"r"); 
//返回的文件类型 
Header("Content-type: application/octet-stream"); 
//按照字节大小返回 
Header("Accept-Ranges: bytes"); 
//返回文件的大小 
Header("Accept-Length: ".filesize($this->_filepath)); 
//这里对客户端的弹出对话框,对应的文件名 
Header("Content-Disposition: attachment; filename=".$this->_filename); 
//修改之前,一次性将数据传输给客户端 
echo fread($file, filesize($this->_filepath)); 
//修改之后,一次只传输1024个字节的数据给客户端 
//向客户端回送数据 
$buffer=1024;// 
//判断文件是否读完 
while (!feof($file)) { 
//将文件读入内存 
$file_data=fread($file,$buffer); 
//每次向客户端回送1024个字节的数据 
echo $file_data; 
} 
fclose($file); 
}else { 
echo "<script>alert('对不起,您要下载的文件不存在');</script>"; 
} 
} 
} 
?>

页面显示的代码:
<script type="text/javascript" src="jquery-1.7.2.js"></script> 
<script type="text/javascript" src="ajax.js"></script> 
<?php 
header("Content-type:text/html;charset=utf8"); 
require('./getfile.php'); 
$scandir=new traverseDir(); 
$scandir->scandir($scandir->currentdir); 
$scandir->currentdir; if (isset($_POST['down_load'])){ 
$items=$_POST['items']; 
$scandir->tozip($items);//将文件压缩成zip格式 
} 
echo "当前的工作目录:".$scandir->currentdir; 
echo "<br>当前目录下的所有文件"; 
?> 
<form action="list.php" method="POST"> 
<table> 
<tr> 
<td></td> 
<td>名称</td> 
<td>大小(KB)</td> 
</tr> 
<?php 
$res=$scandir->fileinfo; 
foreach ($res as $k=>$v){ 
if (!($k=='.' || $k=='..')) {//过滤掉.和.. 
?> 
<tr> 
<td><input type="checkbox" name="items[]" class="filename" value="<?php echo $k;?>"></td> 
<td><?php echo $k; ?></td> 
<td><?php echo number_format($v[0],0); ?></td> 
</tr> 
<?php 
} 
} 
?> 
<tr> 
<td><input type="checkbox" id="selall"><label for="selall">全选</label></td> 
<td><input type="submit" name="down_load" value="打包并下载" id="tozip_tetttt"></td> 
</tr> 
</table> 
</form>
PHP 相关文章推荐
php4的session功能评述(二)
Oct 09 PHP
PHP配置心得包含MYSQL5乱码解决
Nov 20 PHP
PHP 日,周,月点击排行统计
Jan 11 PHP
php 文本文件的读取效率
Feb 10 PHP
joomla jce editor 解决上传中文名文件失败问题
Jun 09 PHP
Codeigniter生成Excel文档的简单方法
Jun 12 PHP
php实现webservice实例
Nov 06 PHP
Linux php 中文乱码的快速解决方法
May 13 PHP
php+jquery+html实现点击不刷新加载更多的实例代码
Aug 12 PHP
PHP随机获取未被微信屏蔽的域名(微信域名检测)
Mar 19 PHP
PHP环形链表实现方法示例
Sep 15 PHP
php实现简易计算器
Aug 28 PHP
Php中文件下载功能实现超详细流程分析
Jun 13 #PHP
php异常处理技术,顶级异常处理器
Jun 13 #PHP
PHP的异常处理类Exception的使用及说明
Jun 13 #PHP
PHP抽象类 介绍
Jun 13 #PHP
MySQL 日期时间函数常用总结
Jun 12 #PHP
PHP简洁函数(PHP简单明了函数语法)
Jun 10 #PHP
php数字游戏 计算24算法
Jun 10 #PHP
You might like
学习php分页代码实例
2013/10/24 PHP
PHP面向对象程序设计之命名空间与自动加载类详解
2016/12/02 PHP
在PHP 7下安装Swoole与Yar,Yaf的方法教程
2017/06/02 PHP
javascript 字符串连接的性能问题(多浏览器)
2008/11/18 Javascript
javascript获得CheckBoxList选中的数量
2009/10/27 Javascript
jquery基础教程之deferred对象使用方法
2014/01/22 Javascript
关于Javascript 对象(object)的prototype
2014/05/09 Javascript
JQuery中使用Ajax赋值给全局变量失败异常的解决方法
2014/08/18 Javascript
JavaScript运行机制之事件循环(Event Loop)详解
2014/10/10 Javascript
jQuery中[attribute=value]选择器用法实例
2014/12/31 Javascript
jquery中JSON的解析方式
2015/03/16 Javascript
JavaScript 面向对象与原型
2015/04/10 Javascript
Jquery基础教程之DOM操作
2015/08/19 Javascript
jQuery旋转木马式幻灯片轮播特效
2015/12/04 Javascript
javascript合并表格单元格实例代码
2016/01/03 Javascript
基于jQuery实现带动画效果超炫酷的弹出对话框(附源码下载)
2016/02/22 Javascript
AngularJS中update两次出现$promise属性无法识别的解决方法
2017/01/05 Javascript
jQuery md5加密插件jQuery.md5.js用法示例
2018/08/24 jQuery
从零开始搭建vue移动端项目到上线的步骤
2018/10/15 Javascript
ES5新增数组的实现方法
2020/05/12 Javascript
[00:31]DOTA2荣耀之路7:Miracle-空血无敌斩
2018/05/31 DOTA
利用python批量给云主机配置安全组的方法教程
2017/06/21 Python
Python实现二叉树的常见遍历操作总结【7种方法】
2019/03/06 Python
pycharm修改file type方式
2019/11/19 Python
使用Python+selenium实现第一个自动化测试脚本
2020/03/17 Python
CSS3实现时间轴特效
2020/11/02 HTML / CSS
解释下面关于J2EE的名词
2013/11/15 面试题
彩色的非洲教学反思
2014/02/18 职场文书
春季防火方案
2014/05/10 职场文书
设计大赛策划方案
2014/06/13 职场文书
体育专业求职信
2014/07/16 职场文书
2014年团员学习十八大思想汇报
2014/09/13 职场文书
毕业生就业推荐表导师评语
2014/12/31 职场文书
2015年保险公司个人工作总结
2015/05/22 职场文书
离婚案件被告代理词
2015/05/23 职场文书
高性能跳频抗干扰宽带自组网电台
2022/02/18 无线电