使用 ZipArchive 压缩到 PPTX 错误

zip with ZipArchive to PPTX errors

遇到了一个奇怪的问题。

我有一个包含 PowerPoint 数据的文件夹,我需要将其压缩然后重命名为 pptx。 如果我手动创建一个 .zip 并将文件复制到其中,然后重命名,它会像预期的那样工作,但是当我使用 ZipArchive 归档数据然后重命名创建的文件时,它不起作用。

以编程方式创建的存档也比手动创建的小几 kB。 存档比较工具告诉我,我在两个 zip 中有完全相同的文件,包括隐藏文件。

但这就是它变得非常奇怪的地方:如果我制作另一个空存档,然后使用简单的[=29=从以编程方式创建的存档中复制粘贴文件], 拖放,当重命名为 .pptx 并且与第一个手动创建的文件大小相同时,新存档将起作用。

    $dir = 'pptx/test/compiled';
    $zip_file = 'pptx/test/file.zip';

    // Get real path for our folder
    $rootPath = realpath($dir);

    // Initialize archive object
    $zip = new \ZipArchive();
    $zip->open($zip_file, \ZipArchive::CREATE | \ZipArchive::OVERWRITE);

    // Create recursive directory iterator
    /** @var SplFileInfo[] $files */
    $files = new \RecursiveIteratorIterator(
        new \RecursiveDirectoryIterator($rootPath),
        \RecursiveIteratorIterator::LEAVES_ONLY
    );

    foreach ($files as $name => $file)
    {
        // Skip directories (they would be added automatically)
        if (!$file->isDir())
        {
            // Get real and relative path for current file
            $filePath = $file->getRealPath();
            $relativePath = substr($filePath, strlen($rootPath) + 1);

            // Add current file to archive
            $zip->addFile($filePath, $relativePath);
        }
    }

    // Zip archive will be created only after closing object
    $zip->close();

更新

这似乎只是 Windows 上的一个问题,当在 Mac 上测试时,它没有问题。

我 运行 再次遇到这个问题,在 LibreOffice 论坛上寻求帮助后(这个问题是针对 Impress 的),我发现在 windows 中归档时使用的文件路径有反斜杠,导致了问题。

我在归档函数中添加了两行来清理路径:

        // Get real and relative path for current file
        $filePath = $file->getRealPath();
        $relativePath = substr($filePath, strlen($rootPath) + 1);

        // Replace backward with forward slashes, for compatibility issues
        $filePath = str_replace('\', '/', $filePath);
        $relativePath = str_replace('\', '/', $relativePath);

        // Add current file to archive
        $zip->addFile($filePath, $relativePath);

现在我的代码运行没有问题。 (我使用 LibreOffice headless 作为 exec() 转换为 pdf,这在以前是行不通的)