简体   繁体   English

PHP 中的 ZipArchive 问题“错误 21 - 是目录”

[英]ZipArchive issue “Error 21 - Is a Directory” in PHP

I'm generating a set of HTML, CSS, and image files and I'm using ZipArchive to compress them into a zip file.我正在生成一组 HTML、CSS 和图像文件,我正在使用 ZipArchive 将它们压缩成一个 zip 文件。 I've confirmed that the generated assets are valid, but when I attempt to zip the set of files, the resulting archive file is not able to be opened.我已经确认生成的资产是有效的,但是当我尝试压缩这组文件时,无法打开生成的存档文件。

I'm not getting any errors in the PHP and when I echo $zip->close() it returns true which I assume to mean that it was able to write to and save the file without issue.我在 PHP 中没有收到任何错误,当我echo $zip->close()它返回 true 时,我认为这意味着它能够毫无问题地写入和保存文件。 Opening the zip with the mac Archive Utility throws this error:使用 mac Archive Utility 打开 zip 会引发此错误:

"Unable to expand "filename.zip" into "Downloads". (Error 21 - Is a directory.) “无法将“filename.zip”扩展为“下载”。(错误 21 - 是目录。)

What might be wrong here?这里可能有什么问题?

Here is the entire PHP script:这是整个 PHP 脚本:

<?php
$ref = $_SERVER["HTTP_REFERER"];
$html = $_REQUEST['html'];
$images = $_REQUEST['images'];

$folder = uniqid();
$prepped = str_replace($ref.'server/php/files/', 'images/', $html);

mkdir("./runways/$folder", 0777);
mkdir("./runways/$folder/images", 0777);
mkdir("./runways/$folder/css", 0777);


file_put_contents('./runways/'.$folder.'/index.html',$prepped);
copy('../../css/runway.css', './runways/'.$folder.'/css/runway.css');

foreach($images as $image) {
    $i = urldecode(str_replace($ref.'server/php/files/', '', $image));
    $idata = file_get_contents('./files/'.$i);
    file_put_contents('./runways/'.$folder.'/images/'.$i, $idata);

}

//echo $ref.'server/php/runways/'.$folder.'/';

$sourcefolder = './runways/'.$folder.'/';
$zipfilename = $folder.'.zip';

$dirlist = new RecursiveDirectoryIterator($sourcefolder);
$filelist = new RecursiveIteratorIterator($dirlist);

ini_set('max_execution_time', 5000);
$zip = new ZipArchive();

if ($zip->open('./zips/'.$zipfilename, ZIPARCHIVE::CREATE) !== TRUE) {
    die ("Could not open archive");
}

foreach ($filelist as $key=>$value) {
    $zip->addFile(realpath($key), $key) or die ("ERROR: Could not add file: $key");
}
$zip->close();

echo $ref.'server/php/zips/'.$zipfilename;

?>

The archive you're creating includes current working directories and parent directories (filenames "." and ".."), which you should leave out.您正在创建的存档包括当前工作目录和父目录(文件名“.”和“..”),您应该忽略它们。 For example if you view the contents of an archive the original code creates, you'll see something like this:例如,如果您查看原始代码创建的存档内容,您将看到如下内容:

$ unzip -l 54b69fbd2de29.zip 
Archive:  54b69fbd2de29.zip
  Length     Date   Time    Name
 --------    ----   ----    ----
        0  01-14-15 09:56   ./runways/54b69fbd2de29/.
        0  01-14-15 09:56   ./runways/54b69fbd2de29/..
        0  01-14-15 09:56   ./runways/54b69fbd2de29/css/.
        0  01-14-15 09:56   ./runways/54b69fbd2de29/css/..
       12  01-14-15 09:56   ./runways/54b69fbd2de29/css/runway.css
        0  01-14-15 09:56   ./runways/54b69fbd2de29/images/.
        0  01-14-15 09:56   ./runways/54b69fbd2de29/images/..
       26  01-14-15 09:56   ./runways/54b69fbd2de29/images/image1.jpg
       31  01-14-15 09:56   ./runways/54b69fbd2de29/images/image2.jpg
        6  01-14-15 09:56   ./runways/54b69fbd2de29/index.html
 --------                   -------
       75                   10 files

You don't want "./runways/54b69fbd2de29/."你不想要“./runways/54b69fbd2de29/”。 or "./runways/54b69fbd2de29/..", etc. Here's one way to fix this, change the final foreach to the following (note also that you don't need $key=>$value, just $key):或“./runways/54b69fbd2de29/..”等。这是解决此问题的一种方法,将最终的foreach更改为以下内容(另请注意,您不需要$key=>$value,只需要$key):

foreach ($filelist as $key) {
    if (!preg_match('/\/\.{1,2}$/',$key)){
        $zip->addFile(realpath($key), $key) or die ("ERROR: Could not add file: $key");
    }
}

The resulting archive is valid, and looks like this:生成的存档是有效的,如下所示:

unzip -l 54b6a39d55a63.zip 
Archive:  54b6a39d55a63.zip
  Length     Date   Time    Name
 --------    ----   ----    ----
       12  01-14-15 10:13   ./runways/54b6a39d55a63/css/runway.css
       26  01-14-15 10:13   ./runways/54b6a39d55a63/images/image1.jpg
       31  01-14-15 10:13   ./runways/54b6a39d55a63/images/image2.jpg
        6  01-14-15 10:13   ./runways/54b6a39d55a63/index.html
 --------                   -------
       75                   4 files

A little background : I have chosen for my website to be wiped, and I have downloaded public_html as a zip file.一点背景:我选择擦除我的网站,并下载了public_html作为 zip 文件。 I was a bit scared I wouldn't be able restore my website once it has been reset.我有点害怕我的网站一旦重置就无法恢复。

A quick solution (and the one that worked for me) is to use an app from the App Store called The Unarchiver .一个快速的解决方案(也是对我有用的一个)是使用 App Store 中名为The Unarchiver的应用程序。 I had this same issue when using a file compressed from the cPanel file manager, and The Unarchiver seemed to fix it.我在使用从 cPanel 文件管理器压缩的文件时遇到了同样的问题, Unarchiver似乎修复了它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM