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 相关文章推荐
php 设计模式之 单例模式
Dec 19 PHP
PHP获取用户的浏览器与操作系统信息的代码
Sep 04 PHP
PHP删除HTMl标签的实现代码
Jun 30 PHP
PHP仿博客园 个人博客(1) 数据库与界面设计
Jul 05 PHP
php读取图片内容并输出到浏览器的实现代码
Aug 08 PHP
PHP中的排序函数sort、asort、rsort、krsort、ksort区别分析
Aug 18 PHP
PHP中使用imagick生成PSD文件缩略图教程
Jan 26 PHP
php中memcache 基本操作实例
May 17 PHP
curl和libcurl的区别简介
Jul 01 PHP
PHP使用Memcache时模拟命名空间及缓存失效问题的解决
Feb 27 PHP
php+mysql实现的二级联动菜单效果详解
May 10 PHP
PHP 中 var_export、print_r、var_dump 调试中的区别
Jun 19 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
DD_belatedPNG,IE6下PNG透明解决方案(国外)
2010/12/06 Javascript
js+html+css实现鼠标移动div实例
2013/01/30 Javascript
js 删除数组的几种方法小结
2014/02/21 Javascript
Extjs grid添加一个图片状态或者按钮的方法
2014/04/03 Javascript
什么是Node.js?Node.js详细介绍
2014/06/01 Javascript
我的Node.js学习之路(三)--node.js作用、回调、同步和异步代码 以及事件循环
2014/07/06 Javascript
js代码验证手机号码和电话号码是否合法
2015/07/30 Javascript
深入解析JavaScript编程中的this关键字使用
2015/11/09 Javascript
jQuery动画效果实现图片无缝连续滚动
2016/01/12 Javascript
JavaScript实现图片滑动切换的代码示例分享
2016/03/06 Javascript
Bootstrap3 多个模态对话框无法显示的解决方案
2017/02/23 Javascript
深入理解vue中的$set
2017/06/01 Javascript
利用jquery去掉时光轴头尾部线条的方法实例
2017/06/16 jQuery
Javacript中自定义的map.js  的方法
2017/11/26 Javascript
JS和JQuery实现雪花飘落效果
2017/11/30 jQuery
JavaScript检查数据中是否存在相同的元素(两种方法)
2018/10/07 Javascript
Smartour 让网页导览变得更简单(推荐)
2019/07/19 Javascript
js 闭包深入理解与实例分析
2020/03/19 Javascript
使用 Github Actions 自动部署 Angular 应用到 Github Pages的方法
2020/07/20 Javascript
JavaScript array常用方法代码实例详解
2020/09/02 Javascript
OpenLayers实现图层切换控件
2020/09/25 Javascript
python使用内存zipfile对象在内存中打包文件示例
2014/04/30 Python
Python中无限元素列表的实现方法
2014/08/18 Python
Django验证码的生成与使用示例
2017/05/20 Python
Python使用爬虫抓取美女图片并保存到本地的方法【测试可用】
2018/08/30 Python
python 处理微信对账单数据的实例代码
2019/07/19 Python
使用html5实现表格实现标题合并的实例代码
2019/05/13 HTML / CSS
福克斯租车:Fox Rent A Car
2017/04/13 全球购物
国际经济与贸易专业大学生职业规划书
2014/03/01 职场文书
秋季校运会广播稿100字
2014/09/18 职场文书
企业法人代表授权委托书
2014/10/02 职场文书
慈善募捐倡议书
2015/04/27 职场文书
入党转正介绍人意见
2015/06/03 职场文书
小学教师暑期培训心得体会
2016/01/09 职场文书
学长教您写论文:经验总结
2019/07/09 职场文书
导游词之峨眉乐山/兵马俑/北京故宫御花园
2019/09/03 职场文书