glob()
Функция glob() в PHP выполняет поиск файлов в директории по шаблону и возвращает массив имён файлов или директорий.
На этой странице рассматривается функция PHP glob(): что она делает, её синтаксис и флаги, поддерживаемые шаблоны в стиле командной оболочки, а также практические примеры — сопоставление нескольких расширений, вывод только директорий, сортировка результатов и рекурсивный обход дерева. Здесь также разбираются типичные ловушки — скрытые файлы, разница между «нет совпадений» и «ошибка», и когда стоит использовать другой инструмент.
Что такое функция glob()?
Функция glob() выполняет поиск путей в директории, соответствующих шаблону в стиле командной оболочки, и возвращает их в виде массива. Название происходит от Unix-механизма globбинга — того же, который использует ваш терминал при вводе ls *.txt.
В отличие от поиска по регулярным выражениям, glob() работает непосредственно с файловой системой, поэтому возвращает только реально существующие пути. Это самый быстрый способ ответить на вопросы вроде «дай мне все .jpg в этой папке» или «какие конфигурационные файлы начинаются с db-».
Синтаксис
glob(string $pattern, int $flags = 0): array|false| Параметр | Описание |
|---|---|
$pattern | Шаблон в стиле командной оболочки (например, images/*.png). Пути могут быть относительными к рабочей директории скрипта или абсолютными. |
$flags | Необязательная битовая маска констант GLOB_*, изменяющих поведение функции. По умолчанию равна 0. |
Возвращаемое значение: массив совпадающих путей, пустой массив, если ничего не найдено, или false при неустранимой ошибке (например, если директорию невозможно прочитать). Поскольку и пустой результат, и ошибка являются «ложными» значениями, для обнаружения ошибок используйте проверку === false.
Шаблоны, поддерживаемые glob()
glob() распознаёт шаблоны в стиле командной оболочки, а не регулярные выражения:
| Шаблон | Совпадает с |
|---|---|
* | любое количество символов (но не /, поэтому остаётся в пределах одного уровня директории) |
? | ровно один символ |
[abc] | один символ из набора — здесь a, b или c |
[a-z] | один символ из диапазона |
[!a-z] | один символ, не входящий в диапазон |
{a,b} | a или b — только если установлен флаг GLOB_BRACE |
Первый пример
<?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;
}
}Этот код ищет все файлы с расширением .txt в текущей рабочей директории и выводит каждое имя на отдельной строке. Обратите внимание на проверку === false: она отличает реальную ошибку от вполне допустимого случая «нет .txt-файлов», который просто возвращает пустой массив, который foreach пропустит.
Флаги glob()
Второй аргумент объединяет одну или несколько констант с помощью побитового оператора OR (|):
| Флаг | Действие |
|---|---|
GLOB_MARK | Добавляет / к каждому имени возвращаемой директории |
GLOB_NOSORT | Возвращает совпадения в порядке, предоставляемом файловой системой, пропуская сортировку по алфавиту по умолчанию (быстрее) |
GLOB_NOCHECK | Если ничего не найдено, возвращает сам шаблон вместо пустого массива |
GLOB_NOESCAPE | Обрабатывает обратные слэши буквально, а не как escape-символы |
GLOB_BRACE | Раскрывает {a,b,c}, чтобы шаблон совпадал с a, b или c |
GLOB_ONLYDIR | Возвращает только записи, являющиеся директориями |
GLOB_ERR | Останавливает выполнение и возвращает false при ошибках чтения вместо их пропуска |
Сопоставление нескольких расширений с GLOB_BRACE
<?php
$images = glob('uploads/*.{jpg,jpeg,png,gif}', GLOB_BRACE);
foreach ($images as $image) {
echo $image . PHP_EOL;
}GLOB_BRACE позволяет охватить четыре расширения одним вызовом, что значительно чище, чем вызывать glob() четыре раза и объединять результаты.
Вывод только поддиректорий
<?php
$dirs = glob('storage/*', GLOB_ONLYDIR);
foreach ($dirs as $dir) {
echo $dir . PHP_EOL;
}С флагом GLOB_ONLYDIR обычные файлы внутри storage/ отфильтровываются, и вы получаете только директории — удобно для перебора папок пользователей, кэш-разделов и т. п.
Сортировка результатов
По умолчанию glob() возвращает совпадения в порядке возрастания по алфавиту. Если нужен другой порядок — например, сначала самые новые файлы — отсортируйте массив самостоятельно:
<?php
$files = glob('logs/*.log');
usort($files, static fn ($a, $b) => filemtime($b) <=> filemtime($a));
print_r($files);Здесь usort() переупорядочивает список по времени изменения (filemtime()), сначала самые новые. Передавайте GLOB_NOSORT в glob(), когда планируете повторную сортировку — это позволяет избежать лишней начальной сортировки в больших директориях.
Рекурсивный поиск
glob() сама по себе не спускается в поддиректории — * никогда не пересекает /. Для обхода всего дерева сочетайте glob() с GLOB_ONLYDIR и рекурсией:
<?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'));Для глубоких или очень больших деревьев PHP-класс RecursiveDirectoryIterator обычно подходит лучше, но этого шаблона достаточно для большинства повседневных задач.
Типичные ловушки
- Скрытые файлы пропускаются. Начальный
*не совпадает с dot-файлами, поэтомуglob('*')не вернёт.envили.gitignore. Сопоставляйте их явно с помощью шаблона видаglob('.*'). - Пустой массив vs.
false. Циклforeachпо пустому массиву безвреден, ноcount(),array_map()и другие функции выдадут предупреждение, еслиglob()вернулаfalse. Сначала выполните проверку=== false. - Нет regex.
glob()понимает только шаблоны командной оболочки. Для сопоставления по регулярным выражениям с существующим списком имён используйтеpreg_grep()или проверяйте отдельные имена с помощьюfnmatch(). - Кроссплатформенные пути. Используйте прямые слэши (
/) в шаблонах даже на Windows или формируйте пути с помощьюDIRECTORY_SEPARATOR, чтобы один и тот же код работал везде.
Когда использовать glob() вместо других инструментов
- Используйте
glob(), когда нужен быстрый отсортированный список путей, соответствующих простому шаблону в одной директории. - Используйте
scandir(), когда нужны все записи директории (включая dot-файлы) и вы планируете фильтровать их самостоятельно. - Используйте
opendir()/readdir()для потоковой обработки больших директорий с минимальным использованием памяти. - Используйте
fnmatch(), чтобы проверить одно имя на соответствие шаблону командной оболочки без обращения к файловой системе.
После получения списка путей функции pathinfo(), is_file() и file_exists() помогут изучить каждый из них. Общую картину см. в обзоре файловой системы PHP.
Заключение
glob() — наиболее удобный способ поиска файлов по шаблону в PHP: передайте шаблон в стиле командной оболочки и получите отсортированный массив реально существующих путей. Не забывайте проверять false там, где важны ошибки, используйте GLOB_BRACE и GLOB_ONLYDIR для лаконичности шаблонов и переходите к рекурсивному итератору, когда нужно обойти дерево целиком.