【问题标题】:ZipArchive issue "Error 21 - Is a Directory" in PHPPHP 中的 ZipArchive 问题“错误 21 - 是一个目录”
【发布时间】:2014-07-09 09:19:59
【问题描述】:

我正在生成一组 HTML、CSS 和图像文件,我正在使用 ZipArchive 将它们压缩成一个 zip 文件。我已确认生成的资产是有效的,但是当我尝试压缩这组文件时,无法打开生成的存档文件。

我在 PHP 中没有收到任何错误,当我 echo $zip->close() 它返回 true 时,我认为这意味着它能够毫无问题地写入和保存文件。使用 mac 存档实用程序打开 zip 会引发此错误:

“无法将“filename.zip”扩展为“下载”。(错误 21 - 是 目录。)

这里可能有什么问题?

这是整个 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;

?>

【问题讨论】:

    标签: php zip server-side archive ziparchive


    【解决方案1】:

    您正在创建的存档包括当前工作目录和父目录(文件名“.”和“..”),您应该忽略它们。例如,如果您查看原始代码创建的存档内容,您会看到如下内容:

    $ 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
    

    您不想要“./runways/54b69fbd2de29/”。或“./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");
        }
    }
    

    生成的存档是有效的,如下所示:

    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
    

    【讨论】:

      【解决方案2】:

      一点背景:我已选择要擦除我的网站,并且已将 public_html 下载为 zip 文件。我有点害怕一旦重置我的网站就无法恢复了。

      一个快速的解决方案(也是对我有用的解决方案)是使用 App Store 中名为 The Unarchiver 的应用程序。我在使用从 cPanel 文件管理器压缩的文件时遇到了同样的问题,The Unarchiver 似乎解决了这个问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-20
        • 2023-03-10
        相关资源
        最近更新 更多