Я написал функцию для поиска файла в определенном каталоге и его подкаталогах. Вы можете ввести имя файла с расширением или без него (базовое имя против имени файла). Второй аргумент — это путь для поиска. Файл найден, если он находится в заданном каталоге, однако он не будет найден, если он находится в подкаталоге. Я пытаюсь использовать рекурсивный вызов функции для поиска в подкаталогах. Есть идеи, что мне не хватает?
public function findFileInPathRecursive($file_to_find, $path) {
if (substr($path, -1) != "/") $path .= "/"; // Add slash at path's end
$files = scandir($path);
foreach($files as $file) {
if (substr($file, 0, 1) == ".") continue; // skip if "." or ".."
if (is_dir($path.$file)) { // if "file" is a directory, call self with the new path
$new_path = $path.$file;
return $this->findFileInPathRecursive($file_to_find, $new_path);
}
else {
if (pathinfo($file)['basename'] == $file_to_find OR pathinfo($file)['filename'] == $file_to_find) {
return $path.$file;
}
}
}
return false;
}
* 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;
}
$files = glob($base.$pattern, $flags);
$files = $files !== false ? $files : [];
Я считаю, что return $this->findFileInPathRecursive($file_to_find, $new_path);
вызовет ранний возврат, когда первая подпапка не содержит файл.
Вы можете избежать этого, возвращаясь только тогда, когда файл найден.
if ($found = $this->findFileInPathRecursive($file_to_find, $new_path)) {
return $found;
}
public function findFileInPathRecursive($file_to_find, $path) {
if (substr($path, -1) != "/") $path .= "/"; // Add slash at path's end
$files = scandir($path);
foreach($files as $file) {
if (substr($file, 0, 1) == ".") continue; // skip if "." or ".."
if (is_dir($path.$file)) { // if "file" is a directory, call self with the new path
$new_path = $path.$file;
// We only want to return file
if ($found = $this->findFileInPathRecursive($file_to_find, $new_path)) {
return $found;
}
}
else {
if (pathinfo($file)['basename'] == $file_to_find OR pathinfo($file)['filename'] == $file_to_find) {
return $path.$file;
}
}
}
return false;
}
Вот оно! Хорошо подмечено, спасибо!!
Можете ли вы отладить это и проверить, приводит ли $путь.$файл к правильному пути для подкаталога?