PHP中使用glob()按目录关键词模糊匹配检索文件的问题
Got it, let's figure out how to fix this. The problem with your current glob() setup is that you're not leveraging wildcards properly to match subdirectories containing your keyword, instead of requiring the full directory name. Here are three reliable approaches to get this working:
1. Combine glob() to Match Directories First, Then Files
This is a straightforward approach: first find all subdirectories under gifs/ that include your keyword, then pull all .gif files from those directories.
$keyword = 'o'; // Your input keyword // Step 1: Grab all subdirectories under gifs/ that contain the keyword $matchingDirs = glob("gifs/*{$keyword}*/", GLOB_ONLYDIR); $allGifs = []; // Step 2: Loop through each matching directory to collect .gif files foreach ($matchingDirs as $dir) { $gifsInDir = glob("{$dir}*.gif"); $allGifs = array_merge($allGifs, $gifsInDir); } // Output the results print_r($allGifs);
Notes:
- The
GLOB_ONLYDIRflag ensures we only get directories, not files. - If your keyword might include wildcard characters like
*or?, useglob_escape()(PHP 7.3+) to sanitize it:$safeKeyword = glob_escape($keyword); $matchingDirs = glob("gifs/*{$safeKeyword}*/", GLOB_ONLYDIR);
2. Use Recursive Directory Iterators (Flexible for Deep Structures)
If your directory tree is more complex (e.g., subdirectories inside the matching ones), using PHP's iterator classes gives you more control.
$keyword = 'o'; $baseDirectory = 'gifs'; $allGifs = []; // Set up a recursive iterator to traverse directories, skipping . and .. $directoryIterator = new RecursiveDirectoryIterator( $baseDirectory, RecursiveDirectoryIterator::SKIP_DOTS ); $recursiveIterator = new RecursiveIteratorIterator( $directoryIterator, RecursiveIteratorIterator::SELF_FIRST // Traverse directories before files ); foreach ($recursiveIterator as $item) { // Check if we're looking at a directory that contains the keyword if ($item->isDir() && str_contains($item->getBasename(), $keyword)) { // Now grab all .gif files in this directory $gifIterator = new DirectoryIterator($item->getPathname()); foreach ($gifIterator as $file) { if (!$file->isDot() && strtolower($file->getExtension()) === 'gif') { $allGifs[] = $file->getPathname(); } } } } print_r($allGifs);
Notes:
str_contains()works in PHP 8.0+. For older versions, replace it withstrpos($item->getBasename(), $keyword) !== false.- The
strtolower()on the extension makes the match case-insensitive (so.GIFfiles are included too).
3. One-Liner Recursive glob() (Simplest for Flat Subdirectories)
If you don't need to handle super deep nested directories, you can use glob() with the GLOB_RECURSE flag to match in one go:
$keyword = 'o'; $allGifs = glob("gifs/*{$keyword}*/**.gif", GLOB_RECURSE); print_r($allGifs);
Notes:
*{$keyword}*matches any subdirectory undergifs/that includes your keyword.**tellsglob()to look recursively inside those directories for.giffiles.- This works best if you don't have too many nested levels, as it can be less efficient than the iterator method for large directory trees.
内容的提问来源于stack exchange,提问作者Dan

