Get all file all subfolders and all hidden file with glob

前端 未结 6 1834
故里飘歌
故里飘歌 2020-12-17 23:28

In my recurive function to zip a whole folders i have this piece of code glob($path. \'/*\') that give me all files and subfolders matching my $path.

Here I read

相关标签:
6条回答
  • 2020-12-18 00:12

    I am answering here in case anyone else is looking as this appears high on Google.

    Solution 1 - glob only

    This uses a glob that is tailored to skip '.' and '..' special directories. It matches anything that:

    • isn't hidden with a '.'
    • is hidden with a '.' but is followed a non '.' character
    • starts with '..' but has at least one character after it
    $globbed = glob("{*,.[!.]*,..?*}", GLOB_BRACE);
    var_dump($globbed);
    

    Solution 2 - globignore

    This is a function to mimic the behaviour of globignore in bash.

    function globignore(array $ignore, $glob, $glob_flags = 0)
    {
        $globbed = glob($glob, $glob_flags);
        return array_filter($globbed, function ($f) use ($ignore)
        {
            $base = basename($f);
            foreach($ignore as $i)
            {
                if ($i == $base) return false;
            }
            return true;
        });
    }
    $globbed = globignore(['.','..'], "{*,.*}", GLOB_BRACE);
    var_dump($globbed);
    

    They appear to execute in almost exactly the same time on my system. Solution 1 requires less code but solution 2 is easier to include more terms to ignore.

    0 讨论(0)
  • 2020-12-18 00:20

    To get all folders/files (even the hidden ones):

    $result = glob($path . '{,.}[!.,!..]*',GLOB_MARK|GLOB_BRACE);
    

    This will prevent listing "." or ".." in the result.

    0 讨论(0)
  • 2020-12-18 00:24

    Probably you've found already the solution, but in case you were looking for a way that gives you the files and directories, recursively and taking care of hidden files, this was what I got:

    function rglob($pattern, $flags = 0) {
        $files = glob($pattern, $flags);
    
        foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR|GLOB_NOSORT) as $dir) {
            $files = array_merge($files, $this->rglob($dir.'/'.basename($pattern), $flags));
        }
    
        return $files;
    }
    
    0 讨论(0)
  • 2020-12-18 00:25

    This returns hidden files and folders, but not . or ..:

    glob($dir . '/{,.}*[!.]', GLOB_MARK | GLOB_BRACE);
    

    Instead of Houmams answer does it return the valid filname ...file.ext as well.

    Tested with $dir="test/" and the following files:

    test/.hiddenfolder/
    test/folder/
    test/...file
    test/...file.ext
    test/.h
    test/.hiddenfile
    test/file
    test/file.ext
    

    Additional information
    Houman tried to target . or .. with [!.,!..], but as this is a character class it is not possible to target strings with a defined length. This means [!.] and [!..] are identical and target both strings not containing an unlimited amount of dots (., .., ..., ...., etc.). Because of that I used [!.] only. Targeting strings is only possible with curly braces like {jpg,png}. You find a good explanation in the php.net comments.

    0 讨论(0)
  • 2020-12-18 00:26

    Have you tried this?

    glob($path. '/{,.}*', GLOB_BRACE);
    
    0 讨论(0)
  • 2020-12-18 00:27

    The glob() method returns an array. So if you want to merge two different glob results...

    $merged = array_merge(glob($dir . '/*'), glob('{,.}*', GLOB_BRACE));
    
    0 讨论(0)
提交回复
热议问题