/* | |
* License: DWTFYW | |
*/ | |
/** | |
* Search recusively for files in a base directory matching a glob pattern. | |
* The `GLOB_NOCHECK` flag has no effect. | |
* | |
* @param string $base Directory to search | |
* @param string $pattern Glob pattern to match files | |
* @param int $flags Glob flags from https://www.php.net/manual/function.glob.php | |
* @return string[] Array of files matching the pattern | |
*/ | |
function glob_recursive($base, $pattern, $flags = 0) { | |
$flags = $flags & ~GLOB_NOCHECK; | |
if (substr($base, -1) !== DIRECTORY_SEPARATOR) { | |
$base .= DIRECTORY_SEPARATOR; | |
} | |
$files = glob($base.$pattern, $flags); | |
if (!is_array($files)) { | |
$files = []; | |
} | |
$dirs = glob($base.'*', GLOB_ONLYDIR|GLOB_NOSORT|GLOB_MARK); | |
if (!is_array($dirs)) { | |
return $files; | |
} | |
foreach ($dirs as $dir) { | |
$dirFiles = glob_recursive($dir, $pattern, $flags); | |
$files = array_merge($files, $dirFiles); | |
} | |
return $files; | |
} |
This comment has been minimized.
This comment has been minimized.
I updated it, thanks! |
This comment has been minimized.
This comment has been minimized.
/**
* Recursive `glob()`.
*
* @author info@ensostudio.ru
*
* @param string $baseDir Base directory to search
* @param string $pattern Glob pattern
* @param int $flags Behavior bitmask
* @return array|string|bool
*/
function glob_recursive(string $baseDir, string $pattern, int $flags = GLOB_NOSORT | GLOB_BRACE)
{
$paths = glob(rtrim($baseDir, '\/') . DIRECTORY_SEPARATOR . $pattern, $flags);
if (is_array($paths)) {
foreach ($paths as $path) {
if (is_dir($path)) {
$subPaths = (__FUNCTION__)($path, $pattern, $flags);
if ($subPaths !== false) {
$subPaths = (array) $subPaths;
array_push($paths, ...$subPaths);
}
}
}
}
return $paths;
} |
This comment has been minimized.
This comment has been minimized.
function rglob(string $patterns, $flags = null): array {
$result = glob($patterns, $flags);
foreach ($result as $item) {
if (is_dir($item)) {
array_push($result, ...rglob($item . '/*', $flags));
}
}
return $result;
} My ¢¢ |
This comment has been minimized.
This comment has been minimized.
function rglob($dir, $flags=null, &$results=[]) {
$ls = glob($dir, $flags);
if (is_array($ls)) {
foreach ($ls as $item) {
if (is_dir($item)) {
$this->rglob($item . '/*', $flags, $results);
}
if (is_file($item)) {
$results[] = $item;
}
}
}
return $results;
} My ¢¢, this one returns just a simple array of all the files (full path) under the top level directory. |
This comment has been minimized.
This comment has been minimized.
@nimbus2300 trash |
This comment has been minimized.
This comment has been minimized.
@haydenk |
This comment has been minimized.
This comment has been minimized.
@markparnaby @UziTech |
This comment has been minimized.
This comment has been minimized.
Fixed it for |
This comment has been minimized.
This comment has been minimized.
@UziTech sorry, but it's too wrong - recursive version of |
This comment has been minimized.
This comment has been minimized.
Says who? I would rather it be consistent and always return an array. |
This comment has been minimized.
This comment has been minimized.
@UziTech established BC practice - check native |
This comment has been minimized.
This comment has been minimized.
@UziTech I agree - the reason I put my (slightly flawed) function in the mix is I just wanted a simple flat array of all the files (recursed) under a parent dir. |
This comment has been minimized.
This comment has been minimized.
@UziTech flag |
This comment has been minimized.
This comment has been minimized.
|
This comment has been minimized.
This comment has been minimized.
I was going for usefulness not consistency with native functions. Especially as far as |
This comment has been minimized.
This comment has been minimized.
@UziTech "useful for me" not same to "useful for anybody". if function name is |
This comment has been minimized.
This comment has been minimized.
If that is what people want they can use your implementation. |
This comment has been minimized.
This comment has been minimized.
That isn't always the most useful. For instance if Also yours will return the string pattern many times when using // dir1
// file1
// dir2
// file2
// dir3
// file3
glob_recursive("/", "file1", GLOB_NOCHECK);
// Your return:
// ["dir1/file1", "file1", "file1"]
// Most likely expected return:
// ["dir1/file1"] |
This comment has been minimized.
This comment has been minimized.
@WinterSilence actually it looks like yours would just return |
This comment has been minimized.
This comment has been minimized.
Also glob("*.txt", GLOB_NOCHECK)
// returns ["*.txt"] if no files found not "*.txt" |
This comment has been minimized.
This comment has been minimized.
Here is a version that works with function glob_recursive($base, $pattern, $flags = 0) {
$glob_nocheck = $flags & GLOB_NOCHECK;
$flags = $flags & ~GLOB_NOCHECK;
function check_folder($base, $pattern, $flags) {
if (substr($base, -1) !== DIRECTORY_SEPARATOR) {
$base .= DIRECTORY_SEPARATOR;
}
$files = glob($base.$pattern, $flags);
if (!is_array($files)) {
$files = [];
}
$dirs = glob($base.'*', GLOB_ONLYDIR|GLOB_NOSORT|GLOB_MARK);
if (!is_array($dirs)) {
return $files;
}
foreach ($dirs as $dir) {
$dirFiles = check_folder($dir, $pattern, $flags);
$files = array_merge($files, $dirFiles);
}
return $files;
}
$files = check_folder($base, $pattern, $flags);
if ($glob_nocheck && count($files) === 0) {
return [$pattern];
}
return $files;
} |
This comment has been minimized.
I add an extra line after line 10 as glob can return false, and your later
array_merge
should be fed an array. You catch the possiblefalse
return later on line 14, so that's good.