首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP ZipArchive文件权限

PHP ZipArchive文件权限
EN

Stack Overflow用户
提问于 2016-03-29 22:41:47
回答 1查看 2.9K关注 0票数 2

当我使用PHP ZipArchive对象创建ZIP归档时,归档中的所有文件的权限都设置为666,尽管原始文件的权限设置为644。

我的脚本正确地压缩了压缩包,只是权限混乱了。

代码语言:javascript
复制
////// Make Template archive object
$templateArchive = new ZipArchive();
$templateArchive->open(PATH_TO_TEMPLATES.'_files/'.$templateName.'/_pack/'.$templateName.'.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE);

$files = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($templateDir."/templates/".$template_archive_name),
    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();

        // relative path is full path, reduced with length of templateDir string and 11 more chars for /templates/
        $relativePath = substr($filePath, strlen($templateDir) + 11);

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

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

另外,我在Mac上做MAMP的工作。我刚刚发现这个问题只有在选择PHP 5.6.10版本时才会出现。当我选择5.5.26时,文件的权限正确。

EN

回答 1

Stack Overflow用户

发布于 2019-01-02 01:45:05

通过在ZipArchive::addFile()语句后添加以下代码,可以在存档的文件中保留Unix权限:

代码语言:javascript
复制
$templateArchive->setExternalAttributesName($relativePath,
                                            ZipArchive::OPSYS_UNIX,
                                            fileperms($filePath) << 16);

这将使用实际文件的权限更新$filePath中条目的外部属性。

Unix权限可以存储在每个条目的外部属性中的ZIP文件中,但是您必须在外部属性中的正确位置执行shift 16 bits to store the permissions,这就是为什么要将<< 16应用于fileperms($filePath)的输出。

ZipArchive::setExternalAttributesName()的文档还提供了一个具有Unix权限设置的示例:https://secure.php.net/manual/en/ziparchive.setexternalattributesname.php

至于目录的权限,您需要使用ZipArchive::addEmptyDir() (因为是ZipArchive::addFile() on a directory will result in an error)添加目录,然后使用ZipArchive::setExternalAttributesName()应用权限,方法与对常规文件相同。

由于RecursiveDirectoryIterator的工作方式,当前目录名称将以/.结尾,而由于ZipArchive::addEmptyDir()的工作方式,存储的目录将以/结尾。要应用ZipArchive::setExternalAttributesName(),您必须提供确切的条目名称,因此我建议在这两种方法中去掉尾部的点。

以下是您的代码经过编辑,以支持保留文件和目录的权限:

代码语言:javascript
复制
////// Make Template archive object
$templateArchive = new ZipArchive();
$templateArchive->open(PATH_TO_TEMPLATES.'_files/'.$templateName.'/_pack/'.$templateName.'.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE);

$files = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($templateDir."/templates/".$template_archive_name),
        RecursiveIteratorIterator::LEAVES_ONLY
);      

foreach ($files as $name => $file)
{               

        // Get real and relative path for current file
        $filePath = $file->getRealPath();

        // relative path is full path, reduced with length of templateDir string and 11 more chars for /templates/
        $relativePath = substr($filePath, strlen($templateDir) + 11);

        // Add regular files
        if (!$file->isDir())
        {
                // Add current file to archive
                $templateArchive->addFile($filePath, $relativePath);
        }
        elseif (substr($relativePath, -2) === "/.")
        {
                // Remove the dot representing the current directory
                $relativePath = substr($relativePath, 0, -1);
                // Add current directory to archive
                $templateArchive->addEmptyDir($relativePath);
        }
        else
        {
                continue;
        }

        $templateArchive->setExternalAttributesName($relativePath,
                ZipArchive::OPSYS_UNIX,
                fileperms($filePath) << 16);
}

// Template Zip archive will be created only after closing object
$templateArchive->close();
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36287554

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档