【问题标题】:How to check if a folder of specific name exists in zip file or not?如何检查zip文件中是否存在特定名称的文件夹?
【发布时间】:2016-07-15 18:27:25
【问题描述】:

我有一个将使用 php ziparchive 函数打开的 zip 文件,稍后我需要检查 zip 中是否存在文件夹?

例如,我有一个文件 ABC.zip。检查zip文件内pqr文件夹中是否有子文件夹xyz,所以如果提取它会是ABC/pqr/xyz

【问题讨论】:

标签: php php-zip-archive


【解决方案1】:

在大多数情况下,您可以使用 ZipArchive::locateName() 方法。 那么简单的解决方案就是

$zip = new \ZipArchive();
$zip->open('ABC.zip');
if($zip->locateName('/pqr/xyz/') !== false) {
    // directory exists
}

但有些档案可能没有在索引中列出目录,即使它们的所有文件都具有正确的内部路径。在这种情况下,locateName 将为目录返回 false。

这里有一个 sn-p 来修复它。您可以扩展 \ZipArchive 或以自己的方式使用它。

class MyZipArchive extends \ZipArchive
{
    /**
     * Locates first file that contains given directory
     *
     * @param $directory
     * @return false|int
     */
    public function locateDir($directory)
    {
            // Make sure that dir name ends with slash
            $directory = rtrim($directory, '/') . '/';
            return $this->locateSubPath($directory);
    }

    /**
     * @param $subPath
     * @return false|int
     */
    public function locateSubPath($subPath)
    {
        $index = $this->locateName($subPath);
        if ($index === false) {
            // No full path found
            for ($i = 0; $i < $this->numFiles; $i++) {
                $filename = $this->getNameIndex($i);
                if ($this->_strStartsWith($filename, $subPath)) {
                    return $i;
                }
            }
        }
        return $index;
    }

    /**
     * Can be replaced with str_starts_with() in PHP 8
     *
     * @param $haystack
     * @param $needle
     * @return bool
     */
    protected function _strStartsWith($haystack, $needle)
    {
        if (strlen($needle) > strlen($haystack)) {
            return false;
        }
        return strpos($haystack, $needle) === 0;
    }
}

然后

$zip = new MyZipArchive();
$zip->open('ABC.zip');
if($zip->locateDir('/pqr/xyz/') !== false) {
    // directory exists
}

【讨论】:

    【解决方案2】:

    我做了一些研究,这就是我想出的,它运行得很好,我添加了 cmets 以便于理解

    <?php
    $zip = new ZipArchive;
    $dir = __DIR__ . '/test'; // directory name
    $zipFileName = __DIR__ . '/ahmad.zip'; // zip name
    $fileName ='ahmad.php'; //file name
    
    // unzip the archive to directory
    $res = $zip->open($zipFileName);
    if ($res === TRUE) {
        $zip->extractTo($dir);
        $zip->close();
    } else {
        echo 'failed, code:' . $res;
    }
    
    // search for the file in the directory
    $array = (scandir($dir));
    if (in_array($fileName, $array)) {
        echo "File exists";
    }
    else {
        echo "file doesn't exist";
    }
    
    // Delete the directory after the search is done
    $it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
    $files = new RecursiveIteratorIterator($it,
                 RecursiveIteratorIterator::CHILD_FIRST);
    foreach($files as $file) {
        if ($file->isDir()){
            rmdir($file->getRealPath());
        } else {
            unlink($file->getRealPath());
        }
    }
    rmdir($dir);
    
    ?>
    

    或者你可以去

    <?php
    $z = new ZipArchive();
    if($z->open('test.zip') === TRUE )
    {
        if ($z->locateName('test.php') !== false)
        {
        echo "file exists";
        }else {
            echo "file doesn't exist";
        }
    }
    else {
        echo 'failed to open zip archive';
    }
    
    ?>
    

    这更容易用户将其发布为答案然后将其删除,因此我也添加了它

    【讨论】:

    • locateName 不检查文件夹,只检查文件! :(
    猜你喜欢
    • 1970-01-01
    • 2018-11-17
    • 1970-01-01
    • 2015-11-19
    • 2018-04-21
    • 2013-01-13
    • 2020-07-01
    • 2021-12-25
    相关资源
    最近更新 更多