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 之 没有mysql支持时的替代方案
Oct 09 PHP
windows下PHP APACHE MYSQ完整配置
Jan 02 PHP
一个简单的PHP&amp;MYSQL留言板源码
Jul 19 PHP
php模块memcache和memcached区别分析
Jun 14 PHP
php 中英文语言转换类
Sep 07 PHP
php输出指定时间以前时间格式的方法
Mar 21 PHP
linux下为php添加iconv模块的方法
Feb 28 PHP
PHP中Array相关函数简介
Jul 03 PHP
php使用PDO从数据库表中读取数据的实现方法(必看)
Jun 02 PHP
基于swoole实现多人聊天室
Jun 14 PHP
PHP PDOStatement::fetch讲解
Jan 31 PHP
thinkphp5.1框架实现格式化mysql时间戳为日期的方式小结
Oct 10 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之Smarty入门
2007/01/04 PHP
php切割页面div内容的实现代码分享
2012/07/31 PHP
PHP中获取时间的下一周下个月的方法
2014/03/18 PHP
CodeIgniter CLI模式简介
2014/06/17 PHP
thinkphp使用phpmailer发送邮件的方法
2014/11/24 PHP
js实现GridView单选效果自动设置交替行、选中行、鼠标移动行背景色
2010/05/27 Javascript
dtree 网页树状菜单及传递对象集合到js内,动态生成节点
2012/04/14 Javascript
由浅入深讲解Javascript继承机制与simple-inheritance源码分析
2015/12/13 Javascript
深入理解jQuery中的事件冒泡
2016/05/24 Javascript
详解Vue.js——60分钟组件快速入门(上篇)
2016/12/05 Javascript
深究AngularJS中ng-drag、ng-drop的用法
2017/06/12 Javascript
javascript帧动画(实例讲解)
2017/09/02 Javascript
JS基于对象的特性实现去除数组中重复项功能详解
2017/11/17 Javascript
原生JS实现旋转轮播图+文字内容切换效果【附源码】
2018/09/29 Javascript
详解webpack打包第三方类库的正确姿势
2018/10/20 Javascript
小程序点击图片实现自动播放视频
2020/05/29 Javascript
vue中$nextTick的用法讲解
2019/01/17 Javascript
vue中对象数组去重的实现
2020/02/06 Javascript
JavaScript实现网页留言板功能
2020/11/23 Javascript
400多行Python代码实现了一个FTP服务器
2012/05/10 Python
python定时检查启动某个exe程序适合检测exe是否挂了
2013/01/21 Python
linux环境下安装pyramid和新建项目的步骤
2013/11/27 Python
python循环监控远程端口的方法
2015/03/14 Python
python实现图片筛选程序
2018/10/24 Python
python 用for循环实现1~n求和的实例
2019/02/01 Python
Python发展史及网络爬虫
2019/06/19 Python
基于python实现雪花算法过程详解
2019/11/16 Python
python实现逻辑回归的示例
2020/10/09 Python
CSS3制作圆形滚动进度条动画的示例
2020/11/05 HTML / CSS
薇姿法国官网:Vichy法国
2021/01/28 全球购物
药学职务聘任书
2014/03/29 职场文书
2015年三年级班主任工作总结
2015/05/21 职场文书
2015年数学教研组工作总结
2015/05/23 职场文书
分析mysql中一条SQL查询语句是如何执行的
2021/06/21 MySQL
入门学习Go的基本语法
2021/07/07 Golang
java项目构建Gradle的使用教程
2022/03/24 Java/Android