liunx下PHP压缩并规划目录结构zip文件

最近遇到一个项目需求, 要求把服务器上的一堆不按命名规则的图片文件压缩出来, 每个文件都要在压缩包里重新命名。
下面记录一下这个问题的解决:

———————————————————————————————————————

一、 服务器扩展ZipArchive

参考安装
在liunxde XSEHLL中输入

wget http://pecl.php.net/get/zip-1.8.3.tgz

自动下载到/root文件下了,也可移到etc文件下同一规范

然后执行在所在目录执行

tar -zxvf zip-1.8.3.tgz
cd zip-1.8.3

此时需要去寻找php-config 文件所在位置
可以输入find / -name php-config 寻找

输入,生成./configure 信息

phpize

注意

我的服务器上有phprize但是提示找不到,故可能是环境变量没配好
故输入export PATH=$PATH:/usr/local/php/bin

注意,最重要的一部,查看这个扩展的安装方式(一般不能通过下面这种方式安装的有readme.txt):

如果输入

./configure --with-php-config=/opt/remi/php56/root/usr/bin/php-config
不通过则不能使用./configure && make && make install安装,阅读readme.txt查看,如果是可执行文件则直接配置可执行文件到环境变量PATH

注意,./configure可能会提示找不到ZLIB, 不能成功编译

因为使用了函数 zlib 来支持数据压缩,因此需要安装 Zlib 模块

解决:本人是centos通过yum :yum install zlib zlib-devel
如果是ubuntu 则:通过sudo库
Complete!

接下来make 和make install还是出现问题,炸了,

注意,编译出现make: *** [php_zip.lo] Error

网上查了,要换个版本,emmmm
换成

wget http://pecl.php.net/get/zip-1.12.4.tg

以上操作再来一遍。

最后,终于成功

make install之后会出现一个zip.so保存的路径,这个路径要添加到php.ini里。

ok, 打开php.ini在“extension=”下面添加如下一段
extension=/opt/remi/php56/root/usr/lib64/php/modules/zip.so
zlib.output_compression = Off 改为 zlib.output_compression = On
zlib.output_compression_level 建议参数值是1~5

修改过后需要重启[php-fpm],如果你是编译安装的那么就用[绝对路径]去启动,如果是直接安装的可以用 service restart

重启apache。

二、PHP扩展类ZipArchive实现压缩解压Zip文件和文件打包下载

关于ZipArchive几点需要注意的地方:

1、打开的模式在linux下不可使用ZipArchive::OVERWRITE来自动创建ZIP包
2、如果要压缩的文件名包含中文,则不能识别,要通过iconv进行编码转化,并用file_exists检测
3、不能对压缩包进行二次压缩
4、PHP的readdir扫描要压缩的文件夹是不按顺序的,但都会扫描一次
5、估计有一个压缩处理池, 如果不close掉,那么这个处理池满了就压缩异常, 一个压缩对象最多处理压缩600个左右文件, 超过不报任何异常,不生成压缩包, 所以遇到大型的压缩项目, 分包压缩吧, 并在扫描文件时检测这个文件时第几个, 每600个文件close掉当前压缩包对象生成文件, 开始往新对象放入文件。

创建对象打开文件
//创建压缩包对象
$zip = new \ZipArchive();
$zipName = iconv("utf-8", "GB2312//IGNORE", C('UPLOAD_PATH').'/所有商品相册'.date('m-d', time()).'('.$i.').zip');
 //这里打开的模式在linux下不可使用ZipArchive::OVERWRITE来自动创建ZIP包
  $zip->open($zipName, \ZipArchive::CREATE);
批量对某个目录进行压缩
 /** 一次压缩
 * 将文件夹打包成zip文件 
 * add by guo 2018年6月3日
 * 循环的读取文件夹下的所有文件和文件夹
 * 其中$filename = readdir($handler)是每次循环的时候将读取的文件名赋值给$filename,
 * 为了不陷于死循环,所以还要让$filename !== false。
 * 定要用!==,因为如果某个文件名如果叫'0',或者某些被系统认为是代表false,用!=就会停止循环
 */
function addFileToZip($path, $zip , $goods_mod, $supplier ,$pre_dir , $goods_num) {
      //$zip为传入总共需要分包的压缩对象列表
    $handler = opendir($path); //打开当前文件夹由$path指定。
 
    while (($filename = readdir($handler)) !== false) {

    if ($filename != "." && $filename != "..") {//文件夹文件名字为'.'和‘..’,不要对他们进行操作
    if (is_dir($path . "/" . $filename)&&is_numeric($filename)) {// 如果读取的某个对象是文件夹,则递归

    //遇到商品id的文件夹把它替换成商品名,查找不到该商品则不递归该文件夹
    $where['goods_id'] = $filename;
    $where['supplier'] = $supplier;

    $goods_name = $goods_mod
    ->where($where)
    ->getField('goods_name',true);
    
    if(!empty($goods_name[0])){
        $goods_num++;
        //

addFileToZip($path . "/" . $filename, $zip, $goods_mod ,$supplier, $goods_name[0], $goods_num);//动态规划递归算法
    }

    } else { //将文件加入zip对象
    //对商品名中带/的进行转义
    //70个商品左右(500左右图片)达到可压缩最大值
    $pre_dir=str_replace("/","",$pre_dir);
    $package_div = ($goods_num/70);

    if (is_int($package_div)) { 
 //估计有一个压缩处理池, 如果不close掉,那么这个处理池满了就压缩异常
$zip[(int)$package_div-1]->close();
    }
        //$pre_dir用于命名这个文件存储的上级目录名字
    $zip[(int)$package_div]->addFile($path . "/" . $filename, $pre_dir.'/'.$filename);
    }
    }
    }
    
    closedir($path);

———————————————————————————————————————
由于不能二次压缩,所以以上的批量压缩算法会生成多个压缩包供前端下载。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容