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 相关文章推荐
探讨php中防止SQL注入最好的方法是什么
Jun 10 PHP
用PHP和Shell写Hadoop的MapReduce程序
Apr 15 PHP
PHP执行Curl时报错提示CURL ERROR: Recv failure: Connection reset by peer的解决方法
Jun 26 PHP
php实现webservice实例
Nov 06 PHP
PHP SPL标准库之数据结构堆(SplHeap)简单使用实例
May 12 PHP
Laravel中使用FormRequest进行表单验证方法及问题汇总
Jun 19 PHP
PHP微信开发之文本自动回复
Jun 23 PHP
php json相关函数用法示例
Mar 28 PHP
PHP自定义函数判断是否为Get、Post及Ajax提交的方法
Jul 27 PHP
PHP mongodb操作类定义与用法示例【适合mongodb2.x和mongodb3.x】
Jun 16 PHP
PHP实现基于3DES算法加密解密字符串示例
Aug 24 PHP
laravel框架中表单请求类型和CSRF防护实例分析
Nov 23 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操作xml
2013/10/27 PHP
完美的2个php检测字符串是否是utf-8编码函数分享
2014/07/28 PHP
PHP管理依赖(dependency)关系工具 Composer的自动加载(autoload)
2014/08/18 PHP
PHP使用内置dir类实现目录遍历删除
2015/03/31 PHP
php使用PDO从数据库表中读取数据的实现方法(必看)
2017/06/02 PHP
JavaScript 判断判断某个对象是Object还是一个Array
2010/01/28 Javascript
基于Jquery的表格隔行换色,移动换色,点击换色插件
2010/12/22 Javascript
js禁止小键盘输入数字功能代码
2011/08/01 Javascript
js动态创建标签示例代码
2014/06/09 Javascript
JavaScript fontcolor方法入门实例(按照指定的颜色来显示字符串)
2014/10/17 Javascript
jQuery中not()方法用法实例
2015/01/06 Javascript
JavaScript获取伪元素(Pseudo-Element)属性的方法技巧
2015/03/13 Javascript
JavaScript判断是否为数字的4种方法及效率比较
2015/04/01 Javascript
JavaScript中数据结构与算法(四):串(BF)
2015/06/19 Javascript
JavaScript基础篇(3)之Object、Function等引用类型
2015/11/30 Javascript
JavaScript 判断一个对象{}是否为空对象的简单方法
2016/10/09 Javascript
详解在Vue中如何使用axios跨域访问数据
2017/07/07 Javascript
微信小程序实时聊天WebSocket
2018/07/05 Javascript
JavaScript面向对象程序设计创建对象的方法分析
2018/08/13 Javascript
vue使用v-for实现hover点击效果
2018/09/29 Javascript
node 标准输入流和输出流代码实例
2019/09/19 Javascript
vue element实现表格合并行数据
2020/11/30 Vue.js
java直接调用python脚本的例子
2014/02/16 Python
在Python中使用PIL模块处理图像的教程
2015/04/29 Python
Python运行报错UnicodeDecodeError的解决方法
2016/06/07 Python
python面向对象多线程爬虫爬取搜狐页面的实例代码
2018/05/31 Python
使用matplotlib中scatter方法画散点图
2019/03/19 Python
浅谈pytorch中torch.max和F.softmax函数的维度解释
2020/06/28 Python
Matplotlib 绘制饼图解决文字重叠的方法
2020/07/24 Python
英国工作场所设备购买网站:Slingsby
2019/05/03 全球购物
巴西购物网站:Onofre Agora
2020/06/08 全球购物
荷兰美妆护肤品海淘网站:Beautinow(中文)
2020/11/22 全球购物
信息技术专业个人自我评价
2013/12/11 职场文书
白酒市场开发计划书
2014/01/09 职场文书
应届生简历自我评价
2015/03/11 职场文书
2016年乡镇综治宣传月活动总结
2016/03/16 职场文书