Graent.Hu 的博客

新浪微薄腾讯微薄

最新碎语:最近感觉有些迷茫,怎么办~

您的位置:Graent.Hu 的博客 >PHP编程> PHP实现文件压缩为zip:PHP扩展ziparchive的使用

PHP实现文件压缩为zip:PHP扩展ziparchive的使用

    本来是给程序做数据库备份的时候用到的,在备份完sql文件之后,提供用户的打包下载,所以就用了PHP的ziparchive扩展,可能是之前没有实际的使用过的原因,被路径的问题搞的一头雾水,所以还是建议大家直接使用物理路径,效率高并且可移植性也会好一些。


    PHP ZipArchive 是PHP自带的扩展类,可以轻松实现ZIP文件的压缩和解压,使用前首先要确保PHP ZIP 扩展已经开启,具体开启方法就不说了,不同的平台开启PHP扩增的方法网上都有,如有疑问欢迎交流。这里整理一下常用的示例供参考。

一、解压缩zip文件


$zip = new ZipArchive;//新建一个ZipArchive的对象
/*
通过ZipArchive的对象处理zip文件
$zip->open这个方法的参数表示处理的zip文件名。
如果对zip文件对象操作成功,$zip->open这个方法会返回TRUE
*/
if ($zip->open('test.zip') === TRUE)
{
$zip->extractTo('images');//假设解压缩到在当前路径下images文件夹的子文件夹php
$zip->close();//关闭处理的zip文件
}
二、将文件压缩成zip文件 



$zip = new ZipArchive;
/*
$zip->open这个方法第一个参数表示处理的zip文件名。
第二个参数表示处理模式,ZipArchive::OVERWRITE表示如果zip文件存在,就覆盖掉原来的zip文件。
如果参数使用ZIPARCHIVE::CREATE,系统就会往原来的zip文件里添加内容。
如果不是为了多次添加内容到zip文件,建议使用ZipArchive::OVERWRITE。
使用这两个参数,如果zip文件不存在,系统都会自动新建。
如果对zip文件对象操作成功,$zip->open这个方法会返回TRUE
*/
if ($zip->open('test.zip', ZipArchive::OVERWRITE) === TRUE)
{
$zip->addFile('image.txt');//假设加入的文件名是image.txt,在当前路径下
$zip->close();
}
三、文件追加内容添加到zip文件 



$zip = new ZipArchive;
$res = $zip->open('test.zip', ZipArchive::CREATE);
if ($res === TRUE) {
$zip->addFromString('test.txt', 'file content goes here');
$zip->close();
echo 'ok';
} else {
echo 'failed';
}
四、将文件夹打包成zip文件 



function addFileToZip($path, $zip) {
$handler = opendir($path); //打开当前文件夹由$path指定。
/*
循环的读取文件夹下的所有文件和文件夹
其中$filename = readdir($handler)是每次循环的时候将读取的文件名赋值给$filename,
为了不陷于死循环,所以还要让$filename !== false。
一定要用!==,因为如果某个文件名如果叫'0',或者某些被系统认为是代表false,用!=就会停止循环
*/
while (($filename = readdir($handler)) !== false) {
if ($filename != "." && $filename != "..") {//文件夹文件名字为'.'和‘..’,不要对他们进行操作
if (is_dir($path . "/" . $filename)) {// 如果读取的某个对象是文件夹,则递归
addFileToZip($path . "/" . $filename, $zip);
} else { //将文件加入zip对象
$zip->addFile($path . "/" . $filename);
}
}
}
@closedir($path);
}

$zip = new ZipArchive();
if ($zip->open('images.zip', ZipArchive::OVERWRITE) === TRUE) {
addFileToZip('images/', $zip); //调用方法,对要打包的根目录进行操作,并将ZipArchive的对象传递给方法
$zip->close(); //关闭处理的zip文件
}
五、ZipArchive方法如下:



几行代码实现PHP文件打包下载zip



<?php   
/**     
 * 没有写成class 或者 function ,需要的朋友自己写,就这么几行。。     
 */  
$filename = "./test/test.zip"; //最终生成的文件名(含路径)   
if(!file_exists($filename)){   
//重新生成文件   
    $zip = new ZipArchive();//使用本类,linux需开启zlib,windows需取消php_zip.dll前的注释   
    if ($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE) {   
        exit('无法打开文件,或者文件创建失败');
    }   
    foreach( $datalist as $val){   
        $attachfile = $attachmentDir . $val['filepath']; //获取原始文件路径   
        if(file_exists($attachfile)){   
            $zip->addFile( $attachfile , basename($attachfile));//第二个参数是放在压缩包中的文件名称,如果文件可能会有重复,就需要注意一下   
        }   
    }   
    $zip->close();//关闭   
}   
if(!file_exists($filename)){   
    exit("无法找到文件"); //即使创建,仍有可能失败。。。。   
}   
header("Cache-Control: public"); 
header("Content-Description: File Transfer"); 
header('Content-disposition: attachment; filename='.basename($filename)); //文件名   
header("Content-Type: application/zip"); //zip格式的   
header("Content-Transfer-Encoding: binary"); //告诉浏览器,这是二进制文件    
header('Content-Length: '. filesize($filename)); //告诉浏览器,文件大小   
@readfile($filename);
?>

    从实际的操作中来看,路径是一个很需要注意的东西:
  1. 使用PHP下载文件的操作需要给出四个header(),可参考:PHP下载文件名中文乱码解决方法和PHP下载流程分析
  2. 计算文件的大小的时候,并不需要先打开文件,通过filesize($filename)就可以看出,如果需要先打开文件的话,filesize可能就会是这样的形式了filesize($filehandle)
  3. 向客户端回送数据的是,记得要设置一个buffer,用来指定每次向客户端输出多少数据,如:$buffer=1023。如果不指定的话,就会将整个文件全部写入内存当中,再一次性的讲数据传送给客户端
  4. 通过feof()函数,可以判断要读取的文件是否读完,如果还没读完,继续读取文件($file_data=fread()),并将数据回送给客户端(echo $file_data)
  5. 每次下载完成后,在客户端都会刷新下,说明了,其实每次都将数据写入到一个临时文件中,等全部下载完成后,再将所有的数据重新整合在一起
  6. 这里我使用的是绝对路径,绝对路径有个好处,就是适应性比较强,而且相对于相对路径,效率更高(免去了查找文件的过程)

下面是在实际的使用中写的一个小的例子,比上面的简单一些:


class Zipper {
    public $msg;
    //put your code here
    public function __construct() {

    }

    public function tozip($fArr ,$path){
        $zip = new \ZipArchive();
        if($zip->open("Data/_bakup/{$path}/{$path}.zip",  \ZipArchive::CREATE) === TRUE){
            for($i = 0;$i < count($fArr);$i++){
                $zip->addFile("Data/_bakup/bak_20160527181844/" .$fArr[$i],$fArr[$i]);
            }
            $zip->close();
            $this->msg = "文件创建成功";
            return TRUE;
        }else{
            $this->msg = "文件创建失败,请检查对应的目录的写权限";
            return FALSE;
        }
    }
    
    public function downfile($path){
        if(is_dir("./Data/_bakup/".$path)){
            $fArr = scandir("./Data/_bakup/".$path);
            array_shift($fArr);
            array_shift($fArr);
            $this->tozip($fArr, $path);
        }        
    }
}


我的微信:graent_hu

欢迎扫码加我和微信好友,有什么问题我们可以一起探讨,有什么需要也随时欢迎发消息给我~

转载请注明出处:

本文标题:PHP实现文件压缩为zip:PHP扩展ziparchive的使用

本文链接:https://www.wlyc.cn/post-20.html

发表评论

路人甲 表情
看不清楚?点图切换