glob()
The glob() function is a built-in PHP function that searches for files in a directory using a pattern. This function returns an array of file names or directory
This page covers the PHP glob() function: what it does, its syntax and flags, the shell-style wildcards it understands, and practical patterns such as matching multiple extensions, listing only directories, sorting results, and walking a tree recursively. It also explains the gotchas that trip people up — hidden files, the difference between "no match" and "error", and when to reach for a different tool.
What is the glob() Function?
The glob() function searches a directory for path names that match a shell wildcard pattern and returns them as an array. The name comes from Unix shell globbing — the same mechanism your terminal uses when you type ls *.txt.
Unlike a regular-expression search, glob() matches against the filesystem directly, so it only ever returns paths that actually exist. It is the quickest way to answer questions like "give me every .jpg in this folder" or "which config files start with db-".
Syntax
glob(string $pattern, int $flags = 0): array|false| Parameter | Description |
|---|---|
$pattern | The shell wildcard pattern to match (e.g. images/*.png). Paths can be relative to the script's working directory or absolute. |
$flags | Optional bit-mask of GLOB_* constants that tweak the behaviour. Defaults to 0. |
Return value: an array of matching path names, an empty array when nothing matches, or false on an unrecoverable error (for example, a directory that cannot be read). Because both an empty result and a failure are "falsy", check with === false when you specifically need to detect errors.
The wildcards glob() understands
glob() recognises shell-style patterns, not regular expressions:
| Pattern | Matches |
|---|---|
* | any number of characters (but not a /, so it stays inside one directory level) |
? | exactly one character |
[abc] | one character from the set — here a, b or c |
[a-z] | one character from a range |
[!a-z] | one character not in the range |
{a,b} | a or b — only when the GLOB_BRACE flag is set |
A first example
<?php
$files = glob('*.txt');
if ($files === false) {
echo 'glob() failed to read the directory.' . PHP_EOL;
} else {
foreach ($files as $file) {
echo $file . PHP_EOL;
}
}This searches for every file ending in .txt in the current working directory and prints each name on its own line. Note the === false check: it distinguishes a real failure from the perfectly valid case of "no .txt files here", which simply yields an empty array that the foreach skips over.
The glob() flags
The second argument combines one or more constants with the bitwise OR operator (|):
| Flag | Effect |
|---|---|
GLOB_MARK | Append a / to each returned directory name |
GLOB_NOSORT | Return matches in the order the filesystem provides them, skipping the default alphabetical sort (faster) |
GLOB_NOCHECK | If nothing matches, return the pattern itself instead of an empty array |
GLOB_NOESCAPE | Treat backslashes literally rather than as escape characters |
GLOB_BRACE | Expand {a,b,c} so the pattern matches a, b or c |
GLOB_ONLYDIR | Return only entries that are directories |
GLOB_ERR | Stop and return false on read errors instead of skipping them |
Matching several extensions with GLOB_BRACE
<?php
$images = glob('uploads/*.{jpg,jpeg,png,gif}', GLOB_BRACE);
foreach ($images as $image) {
echo $image . PHP_EOL;
}GLOB_BRACE lets one call cover four extensions, which is far cleaner than running glob() four times and merging the results.
Listing only sub-directories
<?php
$dirs = glob('storage/*', GLOB_ONLYDIR);
foreach ($dirs as $dir) {
echo $dir . PHP_EOL;
}With GLOB_ONLYDIR, plain files inside storage/ are filtered out, so you get just the directories — handy for iterating over per-user folders, cache buckets, and the like.
Sorting the results
By default glob() returns matches in ascending alphabetical order. If you need a different order — say newest file first — sort the array yourself:
<?php
$files = glob('logs/*.log');
usort($files, static fn ($a, $b) => filemtime($b) <=> filemtime($a));
print_r($files);Here usort() reorders the list by modification time (filemtime()), newest first. Pass GLOB_NOSORT to glob() when you are going to re-sort anyway — it avoids the redundant initial sort on large directories.
Searching recursively
glob() itself does not descend into sub-directories — * never crosses a /. To walk a whole tree, combine glob() with GLOB_ONLYDIR and recursion:
<?php
function findFiles(string $dir, string $pattern): array
{
$files = glob($dir . '/' . $pattern);
foreach (glob($dir . '/*', GLOB_ONLYDIR) as $subDir) {
$files = array_merge($files, findFiles($subDir, $pattern));
}
return $files;
}
print_r(findFiles('src', '*.php'));For deep or very large trees, PHP's RecursiveDirectoryIterator is usually a better fit, but this pattern is enough for most everyday jobs.
Common gotchas
- Hidden files are skipped. A leading
*does not match dot-files, soglob('*')will not return.envor.gitignore. Match them explicitly with a pattern likeglob('.*'). - Empty array vs.
false. Aforeachover an empty array is harmless, butcount(),array_map(), and friends will warn ifglob()returnedfalse. Guard with=== falsefirst. - No regex.
glob()understands shell wildcards only. For regular-expression matching against an existing list of names, usepreg_grep()or test single names withfnmatch(). - Cross-platform paths. Use forward slashes (
/) in patterns even on Windows, or build paths withDIRECTORY_SEPARATOR, so the same code runs everywhere.
When to use glob() vs. other tools
- Use
glob()when you want a quick, sorted list of paths that match a simple wildcard in one directory. - Use
scandir()when you want every entry of a directory (including dot-files) and intend to filter it yourself. - Use
opendir()/readdir()for memory-friendly streaming of huge directories. - Use
fnmatch()to test a single name against a shell pattern without touching the filesystem.
Once you have a list of paths, pathinfo(), is_file(), and file_exists() help you inspect each one. See the PHP Filesystem overview for the bigger picture.
Conclusion
glob() is the most ergonomic way to find files by pattern in PHP: pass a shell-style wildcard, get back a sorted array of real paths. Remember to check for false when errors matter, reach for GLOB_BRACE and GLOB_ONLYDIR to keep patterns tidy, and step up to a recursive iterator when you need to search an entire tree.