【问题标题】:PHP zip results in flat folder structurePHP zip 导致平面文件夹结构
【发布时间】:2015-06-02 19:35:27
【问题描述】:

我正在使用一个前雇员创建的 PHP zip 函数。它压缩文件和文件夹,但生成的 ZIP 文件有两个问题:

一个。它不包括“主”文件夹
湾。它不保留父/子文件夹结构

我想要的是将子文件夹放在父文件夹下,如下所示:

Parent1
   +-- Child1a
   +-- Child1b
Parent2
Parent3
   +-- Child3a
      +-- Subchild3a1
      +-- Subchild3a2

但我最终得到的是 ZIP 文件中的平面文件夹结构:

Parent1
Child1a
Child1b
Parent2
Parent3
Child3a
Subchild3a1
Subchild3a2

如何使用以下代码解决此问题:

<?php

function folderToZip($folder, &$zipFile, $subfolder = null) {
    if ($zipFile == null) {
        return false;
    }

    $folder .= end(str_split($folder)) == "/" ? "" : "/";
    $subfolder .= end(str_split($subfolder)) == "/" ? "" : "/";

    $handle = opendir($folder);

    while ($f = readdir($handle)) {
        if ($f != "." && $f != ".." && $f != "archive") {
                if (is_file($folder . $f)) {
                        if ($subfolder != null)
                        $zipFile->addFile($folder . $f, $subfolder . $f);
                        else
                        $zipFile->addFile($folder . $f);
        } elseif (is_dir($folder . $f)) {
                $zipFile->addEmptyDir($f);
                folderToZip($folder . $f, $zipFile, $f);
            }
        }
    }
}
?>

<?php

$z = new ZipArchive();
$z->open("test.zip", ZIPARCHIVE::CREATE);
folderToZip("c:/path/to/look/for/files/to/compress/", $z);

echo "<br />Done";

$z->close();

$ex_file = "./archive/back-" . date('Ymd_Hi', time()) . ".zip";

rename("test.zip", $ex_file);

?>



编辑:这是最终对我有用的脚本:

<?php

function folderToZip($folder, $zipFile, $subfolder = null) {
    if ($zipFile == null) {
        return false;
    }

    $folder .= end(str_split($folder)) == "/" ? "" : "/";
    $subfolder .= end(str_split($subfolder)) == "/" || $subfolder == NULL ? "" : "/";

    $handle = opendir($folder);

    while ($f = readdir($handle)) {
      if ($f != "." && $f != ".." && $f != "archive") {
                if (is_file($folder . $f)) {
                        $zipFile->addFile($folder . $f, $subfolder . $f);
        } elseif (is_dir($folder . $f)) {
                $zipFile->addEmptyDir($subfolder . $f);
                folderToZip($folder . $f, $zipFile, $subfolder . $f);
            }
        }
    }
}
?>

<?php

$z = new ZipArchive();
$z->open("test.zip", ZIPARCHIVE::CREATE);
folderToZip("c:/path/to/look/for/files/to/compress/", $z);

echo "<br />Done";

$z->close();

$ex_file = "./archive/back-" . date('Ymd_Hi', time()) . ".zip";

rename("test.zip", $ex_file);

?>

【问题讨论】:

  • ZIP 中是否创建了目录? (最好通过在输出中的任何目录后添加 / 来指定它们,即Parent1/
  • 是的,正在创建文件夹,但它们都在同一个父级别。文件夹内有文件 - 除了“主”文件夹中的文件。

标签: php


【解决方案1】:

此代码似乎不正确:

} elseif (is_dir($folder . $f)) {
   $zipFile->addEmptyDir($f);
   folderToZip($folder . $f, $zipFile, $f);
}

我认为应该是:

} elseif (is_dir($folder . $f)) {
   $zipFile->addEmptyDir($subfolder . $f);
   folderToZip($folder . $f, $zipFile, $subfolder . $f);
}

如果不引用 $subfolder 并将其传递回递归函数,您始终会引用 '/' 或 zip 文件的根目录。

【讨论】:

  • 所做的是创建一个大小合适的 ZIP 文件——但它是空的。
  • 问题可能是如果 subfolder 以 null 开头,您正在添加斜杠。在 null 上跳过它,例如:$subfolder .= (end(str_split($subfolder)) == "/" || $subfolder == NULL) ? "" : "/";。在移动设备上无法测试,但这可能会导致失败。此外,最好在 addfile 中指定本地名称,而不考虑子文件夹。
  • 作为 addfile 中指定本地名称的扩展,无论子文件夹如何,我还建议删除:if ($subfolder != null)else $zipFile-&gt;addFile($folder . $f); 部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-09
  • 2012-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-07
相关资源
最近更新 更多