PHP: Фильтровать файлы и каталоги

В этой статье будет говориться об общей проблеме, которая встречается в PHP — это получить список файлов и каталогов. Я расскажу о нескольких основных решений, каждое из которых имеет свои плюсы и минусы.

Сначала я приведу три метода, которые используют очень простые функции PHP, а затем перейдём к более надежным решениям фильтровать файлы и каталоги, которые используют итераторы SPL.

Представим директорию:

\---manager
|
\---user
|   \---document.txt
|   \---data.dat
|   \---style.css
|---article.txt
|---master.dat
|---script.php
|---test.dat
|---text.txt

Применить glob()

Функция glob() позволяет выполнить поиск имен с использованием подстановки символов.

Функция имеет два параметра:

  1. $pattern (обязательный): шаблон поиска
  2. $flags (по желанию): один или несколько флагов, перечисленные в официальной документации
Примеры

Получить список файлов и каталогов, название которых заканчивается на .txt.

<?php
$filelist = glob("*.txt"); ?>

Получим:

array (
  0 => 'article.txt',
  1 =>; 'text.txt'
)

Получить список файлов и каталогов, название которых начинается с te.

<?php
$filelist = glob("te*"); ?>

Получим:

array (
  0 => 'text.txt'
)

Получить список файлов и каталогов, название которых содержит символы ma.

<?php
$filelist = glob("*ma*", GLOB_ONLYDIR); ?>

Получим:

array (
  0 => 'manager'
)

Второй параметр GLOB_ONLYDIR как опция, она исключает файл с называнием master.dat. Это не всегда помогает, для функции glob() нет установок чтобы извлечь только файлы (а не каталоги), которые соответствуют заданному шаблону.

к меню ↑

Применить opendir(), readdir() и closedir()

Функция opendir() открывает директорию с файлами и возвращает дескриптор соединения. Как только обработка извлекается, можно будет использовать readdir(). При каждом вызове, эта функция даст имя следующего файла или каталога внутри открытого каталога. Когда все имена были восстановлены, функция возвращает false. Чтобы закрыть обработку, используется closedir().

В отличие от glob(), этот подход немного сложнее, так как нет параметров, которые помогут вам фильтровать возвращаемые файлы и каталоги. Вы должны выполнить пост-фильтрации, чтобы получить то, что вы хотите.

Примеры

В следующем примере возвращается список всех файлов и каталогов, которые начинается с te.

<?php
$filelist = array();
if ($handle = opendir(".")) {
    while ($entry = readdir($handle)) {
        if (strpos($entry, "te") === 0) {
            $filelist[] = $entry;
        }
    }
    closedir($handle);
}?>

Получим:

array (
  0 => 'text.txt'
)

Пример показывает, как получить только те файлы, которые содержатся по указному пути.

<?php
$filelist = array();
if ($handle = opendir(".")) {
    while ($entry = readdir($handle)) {
        if (is_file($entry)) {
            $filelist[] = $entry;
        }
    }
    closedir($handle);
} ?>

Получим:

array (
  0 => 'article.txt',
  1 => 'master.dat',
  2 => 'script.php',
  3 => 'test.dat',
  4 => 'text.txt'
)
к меню ↑

Применить scandir()

Функция scandir() имеет только один обязательный параметр: путь для чтения. Возвращаемое значение представляет собой массив из файлов и каталогов, содержащихся в указанном пути. Это решение является более кратким и не требует дескриптор.

Пример

Получить список файлов и каталогов, название которых начинается с te.

<?php
$entries = scandir(".");
$filelist = array();
foreach($entries as $entry) {
    if (strpos($entry, "te") === 0) {
        $filelist[] = $entry;
    }
} ?>
к меню ↑

Применить итераторы SPL

<?php
$iterator = new FilesystemIterator(".");
$filelist = array();
foreach($iterator as $entry) {
    if (strpos($entry->getFilename(), "te") === 0) {
        $filelist[] = $entry->getFilename();
    }
}

Получим что и в предыдущих примерах.

Второй пример использует RegexIterator:

<?php
$iterator = new FilesystemIterator(".");
$filter = new RegexIterator($iterator, '/t\.(php|dat)$/');
$filelist = array();
foreach($filter as $entry) {
    $filelist[] = $entry->getFilename();
}

Получим:

array (
  0 => 'script.php',
  1 => 'test.dat'
)
к меню ↑

RecursiveDirectoryIterator

RecursiveDirectoryIterator предоставляет интерфейс для итерации рекурсивно по каталогам файловой системы. Он имеет некоторые полезные методы, такие как GetChildren() и HasChildren().

Пример
<?php
$iterator = new RecursiveDirectoryIterator('.');
$filter = new RegexIterator($iterator->getChildren(), '/t\.(php|dat)$/');
$filelist = array();
foreach($filter as $entry) {
    $filelist[] = $entry->getFilename();
}

Как получить список всех файлов и каталогов смотрите на странице Дерево каталогов на PHP.

htmlhook.ru | Скрипты для веб-приложений