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数组函数序列之krsort()- 对数组的元素键名进行降序排序,保持索引关系
Nov 02 PHP
PHP5中Cookie与 Session使用详解
Apr 30 PHP
解析array splice的移除数组中指定键的值,返回一个新的数组
Jul 02 PHP
关于PHP的curl开启问题探讨
Apr 08 PHP
PHP编程快速实现数组去重的方法详解
Jul 22 PHP
利用PHP访问MySql数据库的逻辑操作以及增删改查的实例讲解
Aug 30 PHP
使用YII2框架实现微信公众号中表单提交功能
Sep 04 PHP
利用PHP访问MySql数据库的逻辑操作以及增删改查的实例讲解
Aug 30 PHP
PHP实现将几张照片拼接到一起的合成图片功能【便于整体打印输出】
Nov 14 PHP
PHP5.6读写excel表格文件操作示例
Feb 26 PHP
解决laravel session失效的问题
Oct 14 PHP
解决Laravel5.2 Auth认证退出失效的问题
Oct 14 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对gzip文件或者字符串解压实例参考
2008/07/25 PHP
php共享内存段示例分享
2014/01/20 PHP
深入浅析PHP的session反序列化漏洞问题
2017/06/15 PHP
关于laravel5.5的定时任务详解(demo)
2019/10/23 PHP
实例:用 JavaScript 来操作字符串(一些字符串函数)
2007/02/15 Javascript
限制文本框输入N个字符的js代码
2010/05/13 Javascript
THREE.JS入门教程(6)创建自己的全景图实现步骤
2013/01/25 Javascript
js和php如何获取当前url的内容
2013/09/22 Javascript
jQuery异步获取json数据方法汇总
2014/12/22 Javascript
基于jQuery和CSS3制作数字时钟附源码下载(jquery篇)
2015/11/24 Javascript
jQuery+jsp实现省市县三级联动效果(附源码)
2015/12/03 Javascript
js实现网页收藏功能
2015/12/17 Javascript
javascript实现九宫格相加数值相等
2020/05/28 Javascript
JavaScript的String字符串对象常用操作总结
2016/05/26 Javascript
JavaScript自学笔记(必看篇)
2016/06/23 Javascript
初探nodeJS
2017/01/24 NodeJs
AngularJs表单校验功能实例代码
2017/02/09 Javascript
详解关于Vue2.0路由开启keep-alive时需要注意的地方
2018/09/18 Javascript
vue实现按需加载组件及异步组件功能
2019/05/27 Javascript
JavaScript canvas动画实现时钟效果
2020/02/10 Javascript
小程序自定义弹框效果
2020/11/16 Javascript
Python的组合模式与责任链模式编程示例
2016/02/02 Python
python安装numpy&amp;安装matplotlib&amp; scipy的教程
2017/11/02 Python
python中pylint使用方法(pylint代码检查)
2018/04/06 Python
详解Django rest_framework实现RESTful API
2018/05/24 Python
Python中最大递归深度值的探讨
2019/03/05 Python
查看python安装路径及pip安装的包列表及路径
2019/04/03 Python
python3的数据类型及数据类型转换实例详解
2019/08/20 Python
当当网软件测试笔试题
2015/11/24 面试题
小学教师培训方案
2014/06/09 职场文书
小学生自我评价100字(15篇)
2014/09/18 职场文书
一份关于丢失公司财物的检讨书
2014/09/19 职场文书
夫妻房产协议书的格式
2014/10/11 职场文书
群众路线组织生活会发言材料
2014/10/17 职场文书
如何写一份成功的商业计划书
2019/06/25 职场文书
nginx之内存池的实现
2022/06/28 Servers