总结:                                                                           

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

分析下技术要点:                                         

  1. 将文件打包成zip格式
  2. 下载文件的功能

要点解析:

  1. 这里我采用的是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()函数,客户端就知道该如何处理文件,是保存还是打开等等


最终的效果如下图所示:

 1 <?php
 2 require'./download.php';
 3 /**
 4  * 遍历目录,打包成zip格式
 5  */
 6     class traverseDir{
 7         public $currentdir;//当前目录
 8         public $filename;//文件名
 9         public $fileinfo;//用于保存当前目录下的所有文件名和目录名以及文件大小
10         public function __construct(){
11             $this->currentdir=getcwd();//返回当前目录
12         }
13         //遍历目录
14         public function scandir($filepath){
15             if (is_dir($filepath)){
16                     $arr=scandir($filepath);
17                     foreach ($arr as $k=>$v){
18                         $this->fileinfo[$v][]=$this->getfilesize($v);
19                     }
20                 }else {
21                     echo "<script>alert('当前目录不是有效目录');</script>";
22                 }
23         }
24         /**
25          * 返回文件的大小
26          *
27          * @param string $filename 文件名
28          * @return 文件大小(KB)
29          */
30         public function getfilesize($fname){
31             return filesize($fname)/1024;
32         }
33
34         /**
35          * 压缩文件(zip格式)
36          */
37         public function tozip($items){
38             $zip=new ZipArchive();
39             $zipname=date('YmdHis',time());
40             if (!file_exists($zipname)){
41                 $zip->open($zipname.'.zip',ZipArchive::OVERWRITE);//创建一个空的zip文件
42                 for ($i=0;$i<count($items);$i++){
43                     $zip->addFile($this->currentdir.'/'.$items[$i],$items[$i]);
44                 }
45                 $zip->close();
46                 $dw=new download($zipname.'.zip'); //下载文件
47                 $dw->getfiles();
48                 unlink($zipname.'.zip'); //下载完成后要进行删除
49             }
50         }
51     }
52 ?>
 1 <?php
 2 /**
 3  * 下载文件
 4  *
 5  */
 6     class download{
 7         protected $_filename;
 8         protected $_filepath;
 9         protected $_filesize;//文件大小
10         public function __construct($filename){
11             $this->_filename=$filename;
12             $this->_filepath=dirname(__FILE__).'/'.$filename;
13         }
14         //获取文件名
15         public function getfilename(){
16             return $this->_filename;
17         }
18
19         //获取文件路径(包含文件名)
20         public function getfilepath(){
21             return $this->_filepath;
22         }
23
24         //获取文件大小
25         public function getfilesize(){
26             return $this->_filesize=number_format(filesize($this->_filepath)/(1024*1024),2);//去小数点后两位
27         }
28         //下载文件的功能
29         public function getfiles(){
30             //检查文件是否存在
31             if (file_exists($this->_filepath)){
32                 //打开文件
33                 $file = fopen($this->_filepath,"r");
34                 //返回的文件类型
35                 Header("Content-type: application/octet-stream");
36                 //按照字节大小返回
37                 Header("Accept-Ranges: bytes");
38                 //返回文件的大小
39                 Header("Accept-Length: ".filesize($this->_filepath));
40                 //这里对客户端的弹出对话框,对应的文件名
41                 Header("Content-Disposition: attachment; filename=".$this->_filename);
42                 //修改之前,一次性将数据传输给客户端
43                 echo fread($file, filesize($this->_filepath));
44                 //修改之后,一次只传输1024个字节的数据给客户端
45                 //向客户端回送数据
46                 $buffer=1024;//
47                 //判断文件是否读完
48                 while (!feof($file)) {
49                     //将文件读入内存
50                     $file_data=fread($file,$buffer);
51                     //每次向客户端回送1024个字节的数据
52                     echo $file_data;
53                 }
54
55                 fclose($file);
56             }else {
57                 echo "<script>alert('对不起,您要下载的文件不存在');</script>";
58             }
59         }
60     }
61 ?>

页面显示的代码:

 1 <script type="text/javascript" src="jquery-1.7.2.js"></script>
 2 <script type="text/javascript" src="ajax.js"></script>
 3 <?php
 4     header("Content-type:text/html;charset=utf8");
 5     require('./getfile.php');
 6     $scandir=new traverseDir();
 7     $scandir->scandir($scandir->currentdir);
 8     $scandir->currentdir;
 9
10     if (isset($_POST['down_load'])){
11         $items=$_POST['items'];
12         $scandir->tozip($items);//将文件压缩成zip格式
13     }
14     echo "当前的工作目录:".$scandir->currentdir;
15     echo "<br>当前目录下的所有文件";
16 ?>
17
18 <form action="list.php" method="POST">
19 <table>
20     <tr>
21         <td></td>
22         <td>名称</td>
23         <td>大小(KB)</td>
24     </tr>
25 <?php
26     $res=$scandir->fileinfo;
27     foreach ($res as $k=>$v){
28         if (!($k=='.' || $k=='..'))    {//过滤掉.和..
29 ?>
30     <tr>
31         <td><input type="checkbox" name="items[]" class="filename" value="<?php echo $k;?>"></td>
32         <td><?php echo $k; ?></td>
33         <td><?php echo number_format($v[0],0); ?></td>
34     </tr>
35 <?php
36         }
37     }
38 ?>
39     <tr>
40         <td><input type="checkbox" id="selall"><label for="selall">全选</label></td>
41         <td><input type="submit" name="down_load" value="打包并下载" id="tozip_tetttt"></td>
42     </tr>
43 </table>
44 </form>

文件打包,下载之使用PHP自带的ZipArchive压缩文件并下载打包好的文件的更多相关文章

  1. 转:PHP 使用ZipArchive压缩文件并下载

    原文来自于:http://courages.us/archives/176 网站上需要提供一些打印数据给用户下载,这些文件每次都需要重新生成,因为随时都会有新的数据产生.网络上关于PHP的压缩功能实现 ...

  2. Java 批量下载excel,并对excel赋值,压缩为zip文件(POI版)

    package com.neusoft.nda.servlet; import java.io.File;import java.io.FileInputStream;import java.io.F ...

  3. 下载远程(第三方服务器)文件、图片,保存到本地(服务器)的方法、保存抓取远程文件、图片 将图片的二进制字节字符串在HTML页面以图片形式输出 asp.net 文件 操作方法

    下载远程(第三方服务器)文件.图片,保存到本地(服务器)的方法.保存抓取远程文件.图片   将一台服务器的文件.图片,保存(下载)到另外一台服务器进行保存的方法: 1 #region 图片下载 2 3 ...

  4. Delphi获取文件名、文件名不带扩展名、文件名的方法;delphi 获取文件所在路径

    取文件名 ExtractFileName(FileName); 取文件扩展名: ExtractFileExt(filename); 取文件名,不带扩展名: 方法一:   Function Extrac ...

  5. 《工程热力学沈维道童钧耕第四版-带书签》高清pdf下载链接

    <工程热力学沈维道童钧耕第四版-带书签>高清pdf下载链接 百度网盘链接:https://pan.baidu.com/s/1dWksA8O3y2JSfIQy5lrU5g 提取码:7x9w ...

  6. 带你体验Folx的智能化下载功能

    BT下载器,也就是种子下载器,其优点是下载的人越多,下载的速度就越快,可以更快速地下载热门资源.这是因为,每个下载种子的用户,在下载的同时,也会上传资源,从而加速其他用户的下载速度. Folx软件,作 ...

  7. 【厚积薄发】Crunch压缩图片的AssetBundle打包

    这是第133篇UWA技术知识分享的推送.今天我们继续为大家精选了若干和开发.优化相关的问题,建议阅读时间10分钟,认真读完必有收获. UWA 问答社区:answer.uwa4d.com UWA QQ群 ...

  8. 一键自动发布ipa(更新svn,拷贝资源,压缩资源,加密图片资源,加密数据文件,加密lua脚本,编译代码,ipa签名,上传ftp)

    一键自动发布ipa(更新svn,拷贝资源,压缩资源,加密图片资源,加密数据文件,加密lua脚本,编译代码,ipa签名,上传ftp) 程序员的生活要一切自动化,更要幸福^_^. 转载请注明出处http: ...

  9. iOS中使用ZipArchive压缩和解压缩文件-备

    为什么我需要解压缩文件 有许多原因能解释为什么我要在工程中使用压缩和解压缩功能,下面是几个常见的原因: 苹果App Store的50M下载限制 苹 果公司出于流量的考虑,规定在非WIFI环境下,限制用 ...

随机推荐

  1. 关于 Pragma 的使用总结

    注意:此文乃是本人阅读多个博客文章后,记下的个人认为重点的地方. 参考文章: 参考1   参考2 #Pragma mark - 用于分离类中的不同功能的方法.(例如,一个 viewController ...

  2. yii2 登录验证

  3. Intellij 常用技巧-持续更新

    1.快速输入 System.out.println(); sout [TAB] 2.删除Module ctrl+alt+shift+s 调出  Project Structure ,也可点击菜单Fil ...

  4. vuejsLearn---通过手脚架快速搭建一个vuejs项目

    开始快速搭建一个项目 通过Webpack + vue-loader 手脚架 https://github.com/vuejs-templates/webpack 按照它的步骤一步一步来 $ npm i ...

  5. python 的var_dump

    from __future__ import print_function from types import NoneType __author__ = "Shamim Hasnath&q ...

  6. 采用阿里的API进行动态域名解析

    #!/usr/bin/env python # -*- coding:utf-8 -*- import os from aliyunsdkcore import client from aliyuns ...

  7. pip安装

    首先安装 python 和python-devel 然后 https://pypi.python.org/pypi/pip/ 下载 tar.gz 解压,安装 tar zxvf pip-8.1.1.ta ...

  8. a biped was detected but cannot be configured properly (Bipe导入Unity 无法正确识别)

    OP stated "I export the biped with 'animation' and 'bake animation' ticked and the correct fram ...

  9. WebForm 内置对象2

    Session: 与Cookies相比 相同点:每一台电脑访问服务器,都会是独立的一套session,key值都一样,但是内容都是不一样的 以上所有内容,都跟cookies一样 不同点: 1.Sess ...

  10. MATLAB的GUI

    % 常使用的对象查看和设置函数 % .get.set函数 ) % 获得句柄值为0的对象的属性,即显示器对象属性 plot([:]); % 绘制一幅图 title('示例'); % 增加text对象 % ...