PHP实现图片批量打包下载功能


Posted in PHP onMarch 01, 2017

上次遇到一个需要打包下载批量图片的问题,找了一下发现这个好方法,记录一下。

首先新建一个zipfile打包类:

<?php
class zipfile {
  var $datasec = array ();
  var $ctrl_dir = array ();
  var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00";
  var $old_offset = 0;
  
  function unix2_dostime($unixtime = 0){
    $timearray = ($unixtime == 0) ? getdate () : getdate($unixtime);    
    if ($timearray ['year'] < 1980){
      $timearray ['year'] = 1980;
      $timearray ['mon'] = 1;
      $timearray ['mday'] = 1;
      $timearray ['hours'] = 0;
      $timearray ['minutes'] = 0;
      $timearray ['seconds'] = 0;
    }
    return (($timearray ['year'] - 1980) << 25) | ($timearray ['mon'] << 21) | ($timearray ['mday'] << 16) | ($timearray ['hours'] << 11) | ($timearray ['minutes'] << 5) | ($timearray ['seconds'] >> 1);
  }
  function add_file($data, $name, $time = 0){
    $name = str_replace('\\', '/', $name);
    
    $dtime = dechex($this->unix2_dostime($time));
    $hexdtime = '\x' . $dtime [6] . $dtime [7] . '\x' . $dtime [4] . $dtime [5] . '\x' . $dtime [2] . $dtime [3] . '\x' . $dtime [0] . $dtime [1];
    eval('$hexdtime = "' . $hexdtime . '";');
    
    $fr = "\x50\x4b\x03\x04";
    $fr .= "\x14\x00";
    $fr .= "\x00\x00";
    $fr .= "\x08\x00";
    $fr .= $hexdtime;
    
    $unc_len = strlen($data);
    $crc = crc32($data);
    $zdata = gzcompress($data);
    $zdata = substr(substr($zdata, 0, strlen($zdata)- 4), 2);
    $c_len = strlen($zdata);
    $fr .= pack('V', $crc);
    $fr .= pack('V', $c_len);
    $fr .= pack('V', $unc_len);
    $fr .= pack('v', strlen($name));
    $fr .= pack('v', 0);
    $fr .= $name;
    
    $fr .= $zdata;
    $fr .= pack('V', $crc);
    $fr .= pack('V', $c_len);
    $fr .= pack('V', $unc_len);
    
    $this->datasec [] = $fr;
    
    $cdrec = "\x50\x4b\x01\x02";
    $cdrec .= "\x00\x00";
    $cdrec .= "\x14\x00";
    $cdrec .= "\x00\x00";
    $cdrec .= "\x08\x00";
    $cdrec .= $hexdtime;
    $cdrec .= pack('V', $crc);
    $cdrec .= pack('V', $c_len);
    $cdrec .= pack('V', $unc_len);
    $cdrec .= pack('v', strlen($name));
    $cdrec .= pack('v', 0);
    $cdrec .= pack('v', 0);
    $cdrec .= pack('v', 0);
    $cdrec .= pack('v', 0);
    $cdrec .= pack('V', 32);
    
    $cdrec .= pack('V', $this->old_offset);
    $this->old_offset += strlen($fr);
    
    $cdrec .= $name;
    
    $this->ctrl_dir[] = $cdrec;
  }
  function add_path($path, $l = 0){
    $d = @opendir($path);
    $l = $l > 0 ? $l : strlen($path) + 1;
    while($v = @readdir($d)){
      if($v == '.' || $v == '..'){
        continue;
      }
      $v = $path . '/' . $v;
      if(is_dir($v)){
        $this->add_path($v, $l);
      } else {
        $this->add_file(file_get_contents($v), substr($v, $l));
      }
    }
  }
  function file(){
    $data = implode('', $this->datasec);
    $ctrldir = implode('', $this->ctrl_dir);
    return $data . $ctrldir . $this->eof_ctrl_dir . pack('v', sizeof($this->ctrl_dir)) . pack('v', sizeof($this->ctrl_dir)) . pack('V', strlen($ctrldir)) . pack('V', strlen($data)) . "\x00\x00";
  }
  
  function add_files($files){
    foreach($files as $file){
      if (is_file($file)){
        $data = implode("", file($file));
        $this->add_file($data, $file);
      }
    }
  }
  function output($file){
    $fp = fopen($file, "w");
    fwrite($fp, $this->file ());
    fclose($fp);
  }
} 

//下面是实例操作过程:
$dfile = tempnam('/tmp', 'tmp');//产生一个临时文件,用于缓存下载文件
$zip = new zipfile();
//----------------------
$filename = 'image.zip'; //下载的默认文件名

//以下是需要下载的图片数组信息,将需要下载的图片信息转化为类似即可
$image = array(
  array('image_src' => 'pic1.jpg', 'image_name' => '图片1.jpg'),
  array('image_src' => 'pic2.jpg', 'image_name' => 'pic/图片2.jpg'),
);

foreach($image as $v){
  $zip->add_file(file_get_contents($v['image_src']), $v['image_name']);
  // 添加打包的图片,第一个参数是图片内容,第二个参数是压缩包里面的显示的名称, 可包含路径
  // 或是想打包整个目录 用 $zip->add_path($image_path);
}
//----------------------
$zip->output($dfile);

// 下载文件
ob_clean();
header('Pragma: public');
header('Last-Modified:'.gmdate('D, d M Y H:i:s') . 'GMT');
header('Cache-Control:no-store, no-cache, must-revalidate');
header('Cache-Control:pre-check=0, post-check=0, max-age=0');
header('Content-Transfer-Encoding:binary');
header('Content-Encoding:none');
header('Content-type:multipart/form-data');
header('Content-Disposition:attachment; filename="'.$filename.'"'); //设置下载的默认文件名
header('Content-length:'. filesize($dfile));
$fp = fopen($dfile, 'r');
while(connection_status() == 0 && $buf = @fread($fp, 8192)){
  echo $buf;
}
fclose($fp);
@unlink($dfile);
@flush();
@ob_flush();
exit();
?>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
解决GD中文乱码问题
Feb 14 PHP
php array_flip() 删除数组重复元素
Jan 14 PHP
php中随机显示图片的函数代码
Jun 23 PHP
PHP flock 文件锁详细介绍
Dec 29 PHP
怎样给PHP源代码加密?PHP二进制加密与解密的解决办法
Apr 22 PHP
ThinkPHP使用smarty模板引擎的方法
Jul 01 PHP
php通过分类列表产生分类树数组的方法
Apr 20 PHP
php实现的RSS生成类实例
Apr 23 PHP
php文件读取方法实例分析
Jun 20 PHP
PHP5.3连接Oracle客户端及PDO_OCI模块的安装方法
May 13 PHP
PHPExcel 修改已存在Excel的方法
May 03 PHP
TP5框架实现签到功能的方法分析
Apr 05 PHP
深入解析PHP中SESSION反序列化机制
Mar 01 #PHP
yii2使用GridView实现数据全选及批量删除按钮示例
Mar 01 #PHP
PHP插件PHPMailer发送邮件功能
Feb 28 #PHP
PHP利用正则表达式将相对路径转成绝对路径的方法示例
Feb 28 #PHP
PHP用正则匹配form表单中所有元素的类型和属性值实例代码
Feb 28 #PHP
PHP中让json_encode不自动转义斜杠“/”的方法
Feb 28 #PHP
PHP连接MYSQL数据库的3种常用方法
Feb 27 #PHP
You might like
php select,radio和checkbox默认选择的实现方法
2010/05/15 PHP
仿Aspnetpager的一个PHP分页类代码 附源码下载
2012/10/08 PHP
php 魔术方法详解
2014/11/11 PHP
PHP基于rabbitmq操作类的生产者和消费者功能示例
2018/06/16 PHP
js 返回时间戳所对应的具体时间
2010/07/20 Javascript
DLL+ ActiveX控件+WEB页面调用例子
2010/08/07 Javascript
js对象之JS入门之Array对象操作小结
2011/01/09 Javascript
解析John Resig Simple JavaScript Inheritance代码
2012/12/03 Javascript
jquery中对于批量deferred的处理方法
2014/01/22 Javascript
JQuery性能优化的几点建议
2014/05/14 Javascript
JavaScript对Cookie进行读写操作实例
2015/07/25 Javascript
Node.js的Web模板引擎ejs的入门使用教程
2016/06/06 Javascript
BootStrap Fileinput初始化时的一些参数
2016/12/30 Javascript
完美解决node.js中使用https请求报CERT_UNTRUSTED的问题
2017/01/08 Javascript
JS表单验证方法实例小结【电话、身份证号、Email、中文、特殊字符、身份证号等】
2017/02/14 Javascript
史上最全JavaScript常用的简写技巧(推荐)
2017/08/17 Javascript
js中bool值的转换及“&amp;&amp;”、“||”、 “!!”详解
2017/12/21 Javascript
jQuery简单判断值是否存在于数组中的方法示例
2018/04/17 jQuery
tracking.js实现前端人脸识别功能
2020/04/16 Javascript
python 提取文件的小程序
2009/07/29 Python
Python3 利用requests 库进行post携带账号密码请求数据的方法
2018/10/26 Python
解决Python下json.loads()中文字符出错的问题
2018/12/19 Python
详解Appium+Python之生成html测试报告
2019/01/04 Python
基于Django统计博客文章阅读量
2019/10/29 Python
tensorflow入门:TFRecordDataset变长数据的batch读取详解
2020/01/20 Python
python为什么要安装到c盘
2020/07/20 Python
一款纯css3实现的鼠标经过按钮特效教程
2014/11/09 HTML / CSS
css3翻牌翻数字的示例代码
2020/02/07 HTML / CSS
html5使用canvas绘制太阳系效果
2014/12/15 HTML / CSS
linux面试题参考答案(3)
2012/09/13 面试题
店长岗位职责
2013/11/21 职场文书
团员的自我评价
2013/12/01 职场文书
学生会工作感言
2015/08/07 职场文书
《认识钟表》教学反思
2016/02/16 职场文书
如何做好员工培训计划?
2019/07/09 职场文书
Python anaconda安装库命令详解
2021/10/16 Python