Deleting files after adding them to an archive prevents the archive's creation

≡放荡痞女 提交于 2019-12-24 03:12:59

问题


    if ($zip->open($zipFile, ZipArchive::CREATE) !== TRUE) {
        (...)
    } else {
        $zip->addFile($tempDir.$fileName.".xls", $fileName.".xls");
        // The array contains the directory structure of the files to add
        foreach ($list_attachments as $dir_name => $attachment_files) {
            if (!empty($attachment_files)) {
                $zip->addEmptyDir($dir_name);
                foreach ($attachment_files as $attachment) {
                    $zip->addFile($tempDir.$dir_name."/".$attachment, $dir_name."/".$attachment));
                    unlink($tempDir.$dir_name."/".$attachment);
                }
                rmdir($tempDir.$dir_name."/");
            }
        }
        $zip->close();
    }

Please don't mind potential typos in the variable names, I rewrote them and the comment in English to make them more readable. If I run the code as is, it will delete the files and the directories but won't create the archive. I ran checks on return values and addEmptyDir, addFile, unlink and rmdir all work fine. However, it seems that removing the files prevents the archive from closing properly, and thus the file isn't created.

I circumvented it by moving the unlink and rmdir calls after the $zip->close(), so the files are only deleted after the archive is created. However, is forces me to have twice the loops, and from what I've gathered looking at the documentation and zip-related questions here there shouldn't be any issue with unlinking like I did. Does anyone know for which reason this could happen?


回答1:


The zip will be finally written to file AFTER you've called $zip->close(). Until this point everything happens in memory, no 'zipping' is done. That's why you can delete the unzipped files only after you've called $zip->close() successfully.

The documentation even says the following:

When a file is set to be added to the archive, PHP will attempt to lock the file and it is only released once the ZIP operation is done. In short, it means you can first delete an added file after the archive is closed.

However, the locks will not prevent you from deleting the files anyway, they are just "hints", the big problem is that the files need to be there for processing on close().


So the inner loop should look like this:

foreach ($attachment_files as $attachment) {
    $zip->addFile($tempDir.$dir_name."/".$attachment, $dir_name."/".$attachment));
    $to_be_unlinked []= $tempDir.$dir_name."/".$attachment;
}

Later on, unlink the files:

...
foreach($to_be_unlinked as $file) {
    unlink($file);
}


来源:https://stackoverflow.com/questions/21528148/deleting-files-after-adding-them-to-an-archive-prevents-the-archives-creation

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!