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 字符截取 解决中文的截取问题,不用mb系列
Sep 29 PHP
PHP中使用gettext来支持多语言的方法
May 02 PHP
php中导出数据到excel时数字变为科学计数的解决方法
Feb 03 PHP
PHP中session变量的销毁
Feb 27 PHP
PHP数据库连接mysql与mysqli对比分析
Jan 04 PHP
PHP二维数组排序简单实现方法
Feb 14 PHP
Linux php 中文乱码的快速解决方法
May 13 PHP
PHP简单实现无限级分类的方法
May 13 PHP
JavaScript实现删除电脑的关机键
Jul 26 PHP
DEDE实现转跳属性文档在模板上调用出转跳地址
Nov 04 PHP
PHP调试及性能分析工具Xdebug详解
Feb 09 PHP
thinkPHP5.1框架路由::get、post请求简单用法示例
May 06 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 mysql与mysqli事务使用说明 分享
2013/08/17 PHP
深入浅析yii2-gii自定义模板的方法
2016/04/26 PHP
PHP isset empty函数相关面试题及解析
2020/12/11 PHP
Avengerls vs Newbee BO3 第二场2.18
2021/03/10 DOTA
Jquery中val()表单取值赋值的实例代码
2013/08/15 Javascript
jQuery过滤选择器:not()方法使用介绍
2014/04/20 Javascript
JavaScript实现的伸展收缩型菜单代码
2015/10/14 Javascript
3种js实现string的substring方法
2015/11/09 Javascript
APP中javascript+css3实现下拉刷新效果
2016/01/27 Javascript
JS代码实现百度地图 画圆 删除标注
2016/10/12 Javascript
AngularJS指令中的绑定策略实例分析
2016/12/14 Javascript
JavaScript实现二分查找实例代码
2017/02/22 Javascript
解决easyui日期时间框ie的兼容的问题
2018/03/01 Javascript
React Router v4 入坑指南(小结)
2018/04/08 Javascript
Vue路由模块化配置的完整步骤
2019/08/14 Javascript
vue-cli打包后本地运行dist文件中的index.html操作
2020/08/12 Javascript
Vant Weapp组件踩坑:picker的初始赋值解决
2020/11/12 Javascript
python简单实现基数排序算法
2015/05/16 Python
Python3如何解决字符编码问题详解
2017/04/23 Python
今天 平安夜 Python 送你一顶圣诞帽 @微信官方
2017/12/25 Python
浅谈pycharm出现卡顿的解决方法
2018/12/03 Python
python实现屏保程序(适用于背单词)
2019/07/30 Python
Python列表切片常用操作实例解析
2020/03/10 Python
如何理解python面向对象编程
2020/06/01 Python
python3处理word文档实例分析
2020/12/01 Python
幼教简历自我评价
2014/01/28 职场文书
乡下人家教学反思
2014/02/01 职场文书
好人好事演讲稿
2014/09/01 职场文书
小学生清明节演讲稿
2014/09/05 职场文书
2015年物业公司保洁工作总结
2015/10/22 职场文书
《索溪峪的野》教学反思
2016/02/19 职场文书
助学金申请书该怎么写?
2019/07/16 职场文书
SQL SERVER中常用日期函数的具体使用
2021/04/08 SQL Server
SQLServer2019 数据库的基本使用之图形化界面操作的实现
2021/04/08 SQL Server
使用canvas对video视频某一刻截图功能
2021/09/25 HTML / CSS
PyTorch中permute的使用方法
2022/04/26 Python