Поиск по папкам с функцией Glob() в PHP

Вы еще пользуетесь opendir() для чтения папок в PHP? Однако, пхп’шная функция glob() – куда более продуманное решение.

Glob() функция удобна, но решение с использованием наименьшего количества строк кода не всегда эффективно – если под эффективностью вы имеете в виду скорость.

Этот вопрос был поднят на сайте Stack Overflow. Пользователь спрашивает о том, как лучше получить список файлов из каталога, исключая “.” и “..” и другие подкаталоги, и вернуть его в виде массива. Было предложено несколько вариантов. С каждым вариантом был проведен тест: прочитать 1000 раз один каталог, содержащий около 400 файлов. Результаты тестирования колебались от 12,4 секунд до 1,2 секунды. Это довольно большая разница, так что стоит обратить внимание на производительность так же, как и на удобство в написании кода. Вот результаты в порядке от самого медленного до самого быстрого способа:

Способ первый

Первый способ заключается в использовании glob() для того, чтобы вернуть массив, а затем отфильтровать каталоги. Это был самый медленный – 12,4 секунды.

[php]foreach(glob(‘*’) as $file_or_dir) {
if( !is_dir($file_or_dir) ){
$files[] = $file_or_dir;
}
}
[/php]

Второй способ

Использование glob() с дополнительным аргументом GLOB_NOSORT, который отключает сортировку. Если вам не нужен отсортированный результат, то стоит обратить на это внимание, потому что этот способ занял 6,4 секунды – почти в два раза меньше.

[php]foreach(glob(‘*’, GLOB_NOSORT) as $file_or_dir) {
if( !is_dir($file_or_dir) ){
$files[] = $file_or_dir;
}
}
[/php]

Третий способ

Функция scandir() является альтернативой, которая заняла 6,5 секунд.

[php]$files = scandir(‘.’);
$result = array();
foreach ($files as $file){
if (($file == ‘.’) || ($file == ‘..’)){
continue;
}
$result[] = $file;
}
[/php]

Использование scandir() в сочетании с array_diff(), чтобы отфильтровать только дот-каталоги, дали чуть более высокую производительность в 6,4 секунды, и это почти тоже самое что и использование glob().

[php]$files = array_diff(scandir(‘.’), array(‘.’, ‘..’));
[/php]

Четвертый способ

Opendir() метод занял 5,3 секунды.

[php]$files = array();
$dir = opendir(‘.’);
while(($currentfile = readdir($dir)) !== false){
if( !is_dir($currentfile) ){
$files[] = $currentfile;
}
}
closedir($dir);
[/php]

Заключительное слово

Использование glob() с GLOB_NOSORT без цикла заняло 2,2 секунды. Можно сделать вывод, что цикл нагружает весь этот процесс.

Или, возможно, is_dir() была источником проблем производительности, потому что если мы используем opendir() и фильтруем результаты, сравнивая имена с “.” и “..”, то получим время до 1,2 секунды.

[php]$files = array();
$dir = opendir(‘.’);
while(($currentFile = readdir($dir)) !== false){
if ( $currentFile == ‘.’ or $currentFile == ‘..’ ){
continue;
}
$files[] = $currentFile;
}
closedir($dir);
[/php]

Конечно, краткий код – это не всегда быстрый код. Быстрая разработка и быстрый код – совсем разные вещи, и вы должны решить, что имеет больший приоритет в каждом конкретном случае.

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

По мотивам http://www.phparch.com/2010/04/putting-glob-to-the-test/

Subscribe
Notify of
6 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
6
0
Would love your thoughts, please comment.x
()
x