使用PHP自带的ZipArchive的一些问题

1.添加文件到压缩文件中,文件太大或者太小添加失败问题。

2.文件路径有中文或特殊字符时不能使用$zip->addFile($file,basename($file));

 

我的例子:

open($zipname,ZipArchive::CREATE|ZipArchive::OVERWRITE))
{
foreach ($files as $file) {    
    if( $zip->addFile($file,basename($file))){
        echo "0";
    }else{
        echo "1";
    } 
}
$zip->close();
}
// Then download the zipped file.
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zipname);
header('Content-Length: ' . filesize($zipname));

 @readfile($zipname);

@unlink($zipname);//删除打包的临时zip文件。文件会在用户下载完成后被删除

上面代码会出现问题,文件太大,太小会输出1,中文路径和特殊字符‘-’会出问题,输出1;

使用 $list = iconv('utf-8', 'gbk', $file);转码并不能解决问题。

上面问题关键,在于

例如:$files[] = "C:\Users\Administrator\Pictures\11111.jpg";

这个字符串存储时已经被转义字符“\”,转义了(不是文件大小和特殊字符和中文问题)。所以必须在存储之前阻止转义。

$titleL="全国大学生电子商务“创新、创意及创业”挑战赛";
// $yuming="http://www.keyan.sjzlg.com:7070";
$date = date("YmdHis");

	require "connet.php";
   $conn=new Mysql();
 	
$sql="SELECT fujian FROM cansai WHERE zhuangtai=3 AND title LIKE '%".$titleL."%' ;";
  $result=$conn->sql($sql);
  
 $result = $result->fetch_all(MYSQLI_ASSOC);
 foreach ($result as $fujian){
	 
	$fujian['fujian']=addcslashes($fujian['fujian'],"\\"); //将转义字符\变成\\防止转义,这一步必须提前到这里,放后面特殊字符\已经转义了
	// echo $fujian['fujian'].",";
	 $fujian['fujian']=$rootPath . $fujian['fujian'];
	 $files[]=$fujian['fujian'];
	 // array_push($files,$fujian['fujian']);

 };


$zipname = 'test.zip';
$zip = new ZipArchive();

if($zip->open($zipname,ZipArchive::CREATE|ZipArchive::OVERWRITE))
{
foreach ($files as $file) {	
	if( $zip->addFile($file,basename($file))){
		echo "0";
	}else{
		echo "1";
	} 
}
$zip->close();
}

 

这样从数据库里拿出来数据直接处理了,就可以了。

 

附上网上一个例子:

真的百度用了很多办法。没有十全十美的。

填坑记录一下

纯PHP代码也试过压缩。但是不能压缩文件夹。只能把文件夹内所有文件压缩到一个文件里面。然后下载。。。。。。换

用PHP 自带的  

ZipArchive 
1.首先加扩展。我用的是集成xampp 。找到PHP/php.ini

加这个 
extension=php_zip.dll 和打开zlib.output_compression=On off改成On

 

2.将扩展文件加在php/ext下

扩展文件下载路径:https://windows.php.net/downloads/pecl/releases/zip/

我的电脑是64x。PHP坂本是5.6的。选择对应的坂本。解压放入

重启apache

 

3.开始正式代码了。

我是thinkphp5.0的。原生和框架都可以使用

首先执行这个代码:

public function zipupload(){
    $path="./emptydir";//要压缩的文件的绝对路径
    $filename='niao';   //生成压缩文件名
$path
= iconv("UTF-8", "GBK", $path);//加这行中文文件夹也ok了
    $this->create_zip($path,$filename);
    if(!file_exists('./' . $filename . '.zip')){
        echo 1;die;
    }
    header("Cache-Control: public");
    header("Content-Description: File Transfer");
    header('Content-disposition: attachment; filename=' . basename($filename . '.zip')); //文件名
    header("Content-Type: application/zip"); //zip格式的
    header("Content-Transfer-Encoding: binary"); //告诉浏览器,这是二进制文件
    header('Content-Length: ' . filesize('./' . $filename. '.zip')); //告诉浏览器,文件大小
    @readfile('./' . $filename . '.zip');//下载到本地
    @unlink('./' . $filename . '.zip');//删除服务器上生成的这个压缩文件
}


function create_zip($path,$filename){
    $zip = new \ZipArchive();
    if($zip->open($filename.'.zip', \ZipArchive::CREATE | \ZipArchive::OVERWRITE)) {
        $this->addFileToZip($path, $zip);//调用方法,对要打包的根目录进行操作,并将ZipArchive的对象传递给方法
        $zip->close(); //关闭处理的zip文件
    }
}


//注意:一般是 $zip = new ZipArchive();如果无法调用就是用 $zip = new \ZipArchive();

//注意:$zip->open($filename.'.zip', ZipArchive::OVERWRITE)=== TRUE如果用这个可能会报错:我改成

$zip->open($filename.'.zip', \ZipArchive::CREATE | \ZipArchive::OVERWRITE)




function addFileToZip($path,$zip){
    $handler=opendir($path); //打开当前文件夹由$path指定。
    while(($filename=readdir($handler))!==false){
        if($filename != "." && $filename != ".."){//文件夹文件名字为'.'和‘..’,不要对他们进行操作
            if(is_dir($path."/".$filename)){
                $this->addFileToZip($path."/".$filename, $zip);
            }else{
                $zip->addFile($path."/".$filename);
            }
        }
    }
    @closedir($path);
}

public function zipupload(){
    $path="./emptydir";//要压缩的文件的绝对路径
    $filename='niao';   //生成压缩文件名
$path
= iconv("UTF-8", "GBK", $path);//加这行中文文件夹也ok了
    $this->create_zip($path,$filename);
    if(!file_exists('./' . $filename . '.zip')){
        echo 1;die;
    }
    header("Cache-Control: public");
    header("Content-Description: File Transfer");
    header('Content-disposition: attachment; filename=' . basename($filename . '.zip')); //文件名
    header("Content-Type: application/zip"); //zip格式的
    header("Content-Transfer-Encoding: binary"); //告诉浏览器,这是二进制文件
    header('Content-Length: ' . filesize('./' . $filename. '.zip')); //告诉浏览器,文件大小
    @readfile('./' . $filename . '.zip');//下载到本地
    @unlink('./' . $filename . '.zip');//删除服务器上生成的这个压缩文件
}
 

function create_zip($path,$filename){
    $zip = new \ZipArchive();
    if($zip->open($filename.'.zip', \ZipArchive::CREATE | \ZipArchive::OVERWRITE)) {
        $this->addFileToZip($path, $zip);//调用方法,对要打包的根目录进行操作,并将ZipArchive的对象传递给方法
        $zip->close(); //关闭处理的zip文件
    }
}
 

注意:一般是 $zip = new ZipArchive();如果无法调用就是用 $zip = new \ZipArchive();

注意:$zip->open($filename.'.zip', ZipArchive::OVERWRITE)=== TRUE如果用这个可能会报错:我改成

$zip->open($filename.'.zip', \ZipArchive::CREATE | \ZipArchive::OVERWRITE)


 

function addFileToZip($path,$zip){
    $handler=opendir($path); //打开当前文件夹由$path指定。
    while(($filename=readdir($handler))!==false){
        if($filename != "." && $filename != ".."){//文件夹文件名字为'.'和‘..’,不要对他们进行操作
            if(is_dir($path."/".$filename)){
                $this->addFileToZip($path."/".$filename, $zip);
            }else{
                $zip->addFile($path."/".$filename);
            }
        }
    }
    @closedir($path);
}
结束。亲测可用!放心。不懂可以问我。
转载自:https://blog.csdn.net/hexiaoniao/article/details/89222983?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_baidulandingword-6&spm=1001.2101.3001.4242

你可能感兴趣的:(php)