Аватар для pixel
26 / 19 / 5
Регистрация: 19.05.2009
Сообщений: 2,290

Рекурсивный поиск файлов

26.06.2013, 17:28. Показов 9928. Ответов 18
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Приветствую.
Есть вот такая рабочая функция:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
function Scan($dir)
{
    if (!preg_match("/\.$/",$dir)){
       if (is_file($dir)) echo "Файл - $dir\n";
        else {
            $d=opendir("$dir");
            while(false !== ($file = readdir($d)))
                Scan("$dir/$file");
            closedir($d);
        }
    }
}
Но мне хотелось бы получить не простой список файлов в браузере, а массив с этими данными, но если я в
PHP
1
       if (is_file($dir)) echo "Файл - $dir\n";
пишу
PHP
1
if (is_file($dir)) $fnames[] = $dir;
то вообще ничего не получаю. Подскажите, как мне получить заполненный массив?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
26.06.2013, 17:28
Ответы с готовыми решениями:

Рекурсивный просмотр папок и файлов
Почему этот код при нахождении поддиректории в данной папке не хочет заходить рекурсивно в поддиректорию? function scan($d=''){ ...

рекурсивный поиск файлов
Всем привет! Нажно реализовать поиск файлов по маске. Набрасал вот такой код: int search_file(string disk, string mask) { char...

Рекурсивный поиск файлов
Привет всем! Пишу программу, имеющую функционал поиска файлов по ключевым словам. Для начала написал программу, которая перебирала бы...

18
 Аватар для AndreyDyakonov
122 / 120 / 7
Регистрация: 21.04.2013
Сообщений: 615
26.06.2013, 17:41
Цитата Сообщение от pixel Посмотреть сообщение
то вообще ничего не получаю
а где вы ничего не получаете? Переменная должна содержать пути. Куда вы ее потом деваете? Кстати ее лучше объявить до первого использования
PHP
1
$fnames=array();
0
 Аватар для pixel
26 / 19 / 5
Регистрация: 19.05.2009
Сообщений: 2,290
26.06.2013, 17:46  [ТС]
все равно ничего не отображается. а отображать я пытаюсь так:
PHP
1
2
3
Scan("some/path");
foreach ($fnames as $i => $value) {
    echo $i.'. '.$value.'<br />';
0
 Аватар для AndreyDyakonov
122 / 120 / 7
Регистрация: 21.04.2013
Сообщений: 615
26.06.2013, 18:26
Цитата Сообщение от pixel Посмотреть сообщение
а отображать я пытаюсь так:
ну как же вы отображаете? переменная $fnames является локальной, она существует только в рамках функции Scan.. В конце этой функции напишите что-то типа
PHP
1
return $fnames;
, а для вывода результата пишите
PHP
1
2
3
4
$arr= Scan('moyput');
foreach($arr as $fname){
echo '<br>',$fname;
}
0
 Аватар для pixel
26 / 19 / 5
Регистрация: 19.05.2009
Сообщений: 2,290
26.06.2013, 18:34  [ТС]
не работает. похоже что из за того, что функция вызывает сама себя что то в массивом происходит.
0
 Аватар для AndreyDyakonov
122 / 120 / 7
Регистрация: 21.04.2013
Сообщений: 615
26.06.2013, 18:46
ну да у вас же рекурсивный вызов, а Scan вызывается без объединения массивов
нужно передавать $fnames по ссылке как второй параметр функции Scan. Если просто суммировать результат объединением массивов, то скорее всего будет переполнение стека, т.к. в каждой рекурсивной Scan будет создаваться свой массив. Попробуйте, если что, подкину рабочий вариант когда время будет.
0
 Аватар для pixel
26 / 19 / 5
Регистрация: 19.05.2009
Сообщений: 2,290
26.06.2013, 19:26  [ТС]
все оказалось гораздо проще. во-первых у хостера какой то глюк был, поэтому ничего не отображалось, а во-вторых, в функцию просто нужно добавить глобал и все начинает работать:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$fnames = array(); 
 
function Scan($dir)
{
global $fnames;
    if (!preg_match("/\.$/",$dir)){
       if (is_file($dir)) $fnames[] = $dir;    
        else {
            $d=opendir("$dir");
            while(false !== ($file = readdir($d)))
                Scan("$dir/$file");
            closedir($d);
        }
    }
}
 
Scan("some/path");
foreach ($fnames as $i => $value) {
    echo $i.'. '.$value.'<br />';
}
прошу критику, нормальный ли это код или возможны проблемы?
P.S. До сего кода я и не знал, что на моем сайте 13 тысяч файлов
0
 Аватар для AndreyDyakonov
122 / 120 / 7
Регистрация: 21.04.2013
Сообщений: 615
26.06.2013, 19:46
Цитата Сообщение от pixel Посмотреть сообщение
прошу критику
global есть глобальное зло... к проблемам сами придете

Не по теме:

а на моем маленько м 25000 файлов.. енциклопия такая, это не показатель

0
 Аватар для pixel
26 / 19 / 5
Регистрация: 19.05.2009
Сообщений: 2,290
26.06.2013, 19:50  [ТС]
ну а обойти это зло как то можно?
0
 Аватар для AndreyDyakonov
122 / 120 / 7
Регистрация: 21.04.2013
Сообщений: 615
26.06.2013, 19:58
это можно обойти даже при правильном использовании процедурного программирования. Глобально обойти, это ооп, но это история другая.

Не по теме:

Можно программировать процедурно, и программирование будет хорошее. Асм - процедурный. никто не мешает на асме программировать движки автомобилей..



Добавлено через 1 минуту

Не по теме:

Стратегия программирования сама придет. Со временем. или с книгами.

0
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
 Аватар для KOPOJI
16844 / 6724 / 880
Регистрация: 12.06.2012
Сообщений: 19,967
26.06.2013, 19:59
лучше не использовать global, а передавать по ссылке, ну или использовать static (имхо)..
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function Scan($dir)
{
    static $fnames = array();
    if($d=opendir($dir))
    {
        while(false !== ($file = readdir($d)))
        {
            if ($file == '.' || $file == '..')
                continue;
            if(is_dir($dir . DIRECTORY_SEPARATOR . $file))
                Scan($dir . DIRECTORY_SEPARATOR . $file);
            else
                $fnames[] = $file;
        }
        closedir($d);
    }
    return $fnames;
}
 
echo '<pre>';
var_dump(Scan('.'));
1
 Аватар для AndreyDyakonov
122 / 120 / 7
Регистрация: 21.04.2013
Сообщений: 615
26.06.2013, 20:00
global как goto, который со временем запретили. Можете не верить, но global зло
0
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
 Аватар для KOPOJI
16844 / 6724 / 880
Регистрация: 12.06.2012
Сообщений: 19,967
26.06.2013, 20:01
тоже самое с передачей по ссылке
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function Scan($dir, $fnames=array())
{
    if($d=opendir($dir))
    {
        while(false !== ($file = readdir($d)))
        {
            if ($file == '.' || $file == '..')
                continue;
            if(is_dir($dir . DIRECTORY_SEPARATOR . $file))
                Scan($dir . DIRECTORY_SEPARATOR . $file, &$fnames);
            else
                $fnames[] = $file;
        }
        closedir($d);
    }
    return $fnames;
}
 
echo '<pre>';
var_dump(Scan('.'));
1
 Аватар для pixel
26 / 19 / 5
Регистрация: 19.05.2009
Сообщений: 2,290
26.06.2013, 20:03  [ТС]
со временем, это конечно хорошо, но если до этого времени из за косяков в коде можно будет потерять информацию - как то не очень хороший опыт.
0
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
 Аватар для KOPOJI
16844 / 6724 / 880
Регистрация: 12.06.2012
Сообщений: 19,967
26.06.2013, 20:05
Цитата Сообщение от AndreyDyakonov Посмотреть сообщение
который со временем запретили
никто его не запрещал. И есть ситуации, когда удобнее им воспользоваться. Только ухудшается "удобство" кода, что-ли, бегать искать "где же эта 'метка:'", поэтому считается плохим стилем. Но использовать не запрещается.
Вот, к примеру, достаточно известный HtmlParser https://github.com/gisle/html-... /hparser.c
0
 Аватар для AndreyDyakonov
122 / 120 / 7
Регистрация: 21.04.2013
Сообщений: 615
26.06.2013, 20:13
что-то я заболтался, вот класс (с сокращениями) который все порешает:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
class FileSystem {
    public static function createDir($whole_path) {
        $dirs = explode('/', trim($whole_path, '/'));
        $current = '';
        $ok = true;
        foreach ($dirs as $dir) {
            if (strlen($dir) == 0)
                continue;
            $current.=$dir;
            if (!is_dir($current)) {
                $ok = ($ok & @mkdir('./' . $current));
                if (!$ok)
                    break;
            }
            $current.='/';
        }
 
        return $ok;
    }
 
    public static function deleteDir($path) {
        if (!@is_dir($path))
            return;
        if ($handle = @opendir($path)) {
 
            while (false !== ($file = @readdir($handle))) {
                if ($file == '.' || $file == '..')
                    continue;
                $file = self::ptSep($path) . $file;
                if (@is_dir($file)) {
                    self::deleteDir($file);
                    @rmdir($file);
                } else {
                    @unlink($file);
                }
            }
 
            @closedir($handle);
            @rmdir($path);
        }
    }
 
    private static function fileList($path, $with_dir, &$file_list) {
        if ($handle = opendir($path)) {
            $ok = true;
            while (false !== ($file = readdir($handle))) {
                if ($file == '.' || $file == '..')
                    continue;
                $file = self::ptSep($path) . $file;
                if (is_dir($file)) {
                    if ($with_dir)
                        $file_list[] = $file; // iconv('windows-1251', 'UTF-8',$file);
                    if (!self::fileList($file, $with_dir, $file_list)) {
                        $ok = false;
                        break;
                    }
                } else {
                    $file_list[] = $file; // iconv('windows-1251', 'UTF-8',$file);
                }
            }
            closedir($handle);
            return $ok;
        }else
            return false;
    }
 
    public static function getFiles($path, $with_dir = false) {
        if (!is_dir($path))
            return NULL;
        $file_list = array();
        if (!self::fileList($path, $with_dir, $file_list))
            return null;
        return $file_list;
    }
 
}
Для вашей задачи - функция fileList

Добавлено через 7 минут
я под свои задачи делал, возможно придется где-то поменять private на public...
1
 Аватар для pixel
26 / 19 / 5
Регистрация: 19.05.2009
Сообщений: 2,290
26.06.2013, 20:27  [ТС]
Цитата Сообщение от KOPOJI Посмотреть сообщение
тоже самое с передачей по ссылке
PHP
1
2
3
4
 
...
                Scan($dir . DIRECTORY_SEPARATOR . $file, &$fnames);
...
Подскажите, а что означает знак & перед $fnames?
0
 Аватар для AndreyDyakonov
122 / 120 / 7
Регистрация: 21.04.2013
Сообщений: 615
26.06.2013, 20:31
бляха муха, пересокращал. в класс, для работоспособности добавьте функцию
PHP
1
2
3
4
5
6
static function ptSep($test_path) {
        if ($test_path[mb_strlen($test_path) - 1] != '/') {
            return $test_path . '/';
        }
        return $test_path;
    }
Добавлено через 1 минуту
Цитата Сообщение от pixel Посмотреть сообщение
а что означает знак & перед $fnames
то что переменная, будь то массив или даже объект передается по ссылке, т.е. она может быть изменена внутри функции и вне функции изменения будут видны.
Хотя объекты и так передаются по ссылке.
1
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
 Аватар для KOPOJI
16844 / 6724 / 880
Регистрация: 12.06.2012
Сообщений: 19,967
26.06.2013, 20:49
Цитата Сообщение от pixel Посмотреть сообщение
что означает знак & перед $fnames?
ответ в начале сцитированного вами Передача по ссылке
Имхо, Vovan-VE хорошо об этом рассказал Как работают ссылки в PHP
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
26.06.2013, 20:49
Помогаю со студенческими работами здесь

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

Рекурсивный поиск файлов
Была задача разработать простую функцию, которая по заданной маске ищет все возможные файлы в любой папке ну понятно. ФУнкция работает не...

Рекурсивный поиск файлов
Доброго времени суток. Нужна помощь есть код который вполне подходит мне он ищет диски на компе потом в каждом диске ищет файлы по маске,...

Рекурсивный Поиск файлов
Доброго всем времени суток, я к вам со следующей проблемой: необходимо разобраться с рекурсивным поиском файлов на всем компьютере...

Рекурсивный поиск файлов в C# .NET
Как реализовать? Нужно получить полный путь к файлу, включая имя файла. Есть функция FindInFiles для поиска в файлах, параметром...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Опции темы

Новые блоги и статьи
EmBitz, создание проекта, отладка, прошивка
locm 15.07.2025
Создание проекта для Blue Pill (STM32F103C8T6) в EmBitz 2. 30, написания кода blink, запуск отладки в ОЗУ, заливка релизной прошивки во flash используя ST-Link и др. . . .
Трассировка корутин Kotlin с OpenTelemetry
mobDevWorks 14.07.2025
Асинхронное программирование меняет правила игры, особенно когда речь заходит о трассировке операций. В Kotlin с его корутинами эта проблема приобретает особый оттенок, который я хотел бы детально. . .
Облачные приложения на Rust: руководство по архитектуре микросервисов
golander 13.07.2025
Когда я впервые взялся за проектирование облачной платформы для одного из наших клиентов, выбор стоял между привычными Go и Java. Но после нескольких месяцев разработки микросервисной системы,. . .
Как Node.js выполняет асинхронные операции
Reangularity 13.07.2025
Каждый раз, когда я рассказываю про Node. js, возникает один и тот же вопрос: "Как эта штука может быть быстрой, если JavaScript — однопоточный язык?" И это действительно кажется парадоксом. Ведь в. . .
Как писать чистый, тестируемый и качественный код на Python
py-thonny 12.07.2025
Помню свой первый проект на Python. Работал тогда быстро, грязно, лишь бы работало. Код был похож на запутанный клубок - переменные по одной букве, функции на 200 строк, комментарии отсутствовали как. . .
Blazor и контроллер сервопривода IoT Meadow Maple
Wired 11.07.2025
Я решил разобраться, как можно соединить современные веб-технологии с миром "железа". Интересная комбинация получилась из Blazor в качестве веб-интерфейса и микроконтроллера Meadow с его веб-сервером. . .
Генерация OpenQASM из кода Q#
EggHead 10.07.2025
Летом 2024-го я начал эксперименты с библиотекой Q# Bridge, и знаете что? Она оказалась просто находкой для тех, кто работает на стыке разных квантовых экосистем. Основная фишка этой библиотеки -. . .
Изучаем новый шаблон ИИ-чата .NET AI Chat Web App
stackOverflow 10.07.2025
В . NET появилось интересное обновление - новый шаблон ИИ-чата под названием . NET AI Chat Web App. Когда я впервые наткнулся на анонс этого шаблона, то сразу понял, что Microsoft наконец-то. . .
Результаты исследования от команды ARP (июль 2025 г.)
Programma_Boinc 10.07.2025
Результаты исследования от команды ARP (июль 2025 г. ) Африканский проект по дождям (ARP) World Community Grid снова запущен! Мы рады поделиться обновленной информацией о нашем прогрессе с осени. . .
Angular vs Svelte - что лучше?
Reangularity 09.07.2025
Сегодня рынок разделился на несколько четких категорий: тяжеловесы корпоративного уровня (Angular), гибкие универсалы (React), прогрессивные решения (Vue) и новая волна компилируемых фреймворков. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru