как мне реализовать рекурсивный вывод папок с помощью html+php списка select

всем привет.

хочу реализовать рекурсивный вывод папок с помощью html+php списка select

  • т.е. на странице есть 1й список ТОЛЬКО папок корня каталога.
  • При выборе в нем нужной папки ниже появлялся бы 2й список с ТОЛЬКО подкаталогами,
  • если есть еще вложенные папки - ниже 3й список, ну и т.д.
  • Если в папке есть еще и файлы, то они просто отобразятся ссылками ниже (ну или чем-нить).
  • Соответственно, если меняем в 1ом списке что-то, то отобразятся только 1й список (корень) и 2й (с вложенными).

вот с чего начал:

2 файла. 1й работает на клиенте, 2й на сервере, пробовал зациклить - наверное глупо. Не пойму как/вернее где script обрабатывается,

в общем - помогите.

Geek Brains не предлагать!!!

Вообще, именно такая реализация - чёто многа кода мне кажется)))

так же не нашел ни чего путнего про onChange. в php его, как я понял, не обработать, т.е. скрипты. но вот рассираться из примеров в инете не хочется.
во всем этом (php js html и т.д.)сижу 2 недели. и да - я читаю, читаю маны)) многое пока не понятно.

по ходу кода немного вопросов. метод POST предпочтительнее

php select-dir.php

<?php
global $x; // надо ли?
$x = 0;// может использоваться как счетчик
// запись в файл $x для out.txt
$fopen = fopen('sel.txt', 'w');
chmod("sel.txt", 0777); // ни чего не говорите про права )))
fputs($fopen,'<?php $dir = $_POST[\''.$x.'\']; $x = '.$x.';?>');
fclose($fopen);

$dir = 'images'; // корневая папка
    $dir_out = @opendir($dir) or die("Ошибка при открытии папки !!!");
    $files = scandir($dir, 0);
    
    $select = '<form id = "sel_dir'.$x.'">';  //привязка формы к скрипту
    // name $x - для вывода в out.php // upIncome() имя функции для скрипта 
    $select .= '<SELECT name ="'.$x.'" onchange="upIncome()">';
    $select .= '<option hidden="none">выбор '.$x.'</option>';
    // не стал использовать WHILE, мне так яснее ситуация
        for($i = 2; $i < count($files); $i++) {
            $infiles = $files[$i];
            $dir_out = $dir .'/'. $infiles;
                if (is_dir($dir_out)) { //проверяем что это папка
   // на всякий случай колбасим все (вдруг где-то че-то проверять)
                    $select .= '<option name ="'.$infiles.'" value="'.$infiles.'">' . $infiles .'</option>';
                }
        }
    $select .= '</select>';
    $select .= '</form>';
    echo $select;
?>

<!-- здесь вывод -->
<div class="from-server"></div>

<script>
async function upIncome(){
        var x = <?php echo $x ?>;
 <!-- как и что можно сюда добавить? -->
        let response = await fetch('out.php',{
        method: 'POST',
        body: new FormData(document.querySelector('#sel_dir'+x)),
        });
    ;
 <!-- querySelector - что это?-->
    document.querySelector('.from-server').innerHTML = await response.text();
    }
</script>

php out.php

<?php
global $x; // надо ли?
include 'sel.txt';
echo '<h1>
        папка: '.$dir.'<br>
 // по идее - если б в 1ом файле был бы еще 2й список
 // в той же форме <form id = "sel_dir'.$x.'">
 // то можно было б вывести и его значение <select NAME=""
     </h1>';

// нужно еще как-то $dir менять на $dir/вложенная_дир. массив может ?
?>

Ответы (1 шт):

Автор решения: addmaster

РЕШЕНО

В общем,прошла неделя... ни кто ни где не ответил, недолгие вечера.. немного манокура (reading the man). Вот, что у меня получилось. единственное - выпадающий список не добавляется, а обновляется - но к этому и шло. Для хранения данных используется сессия (для многопользования (multiplayer)). Сразу скажу - не все мне нравится в коде, также часть кода заимствованна здесь

главное - работает ))

select-dir.php

<?php
session_start(); // открываем сессию
// проверяем есть ли в ней данные, если нет - то создаем массив 
// и его первый элемент, который является КОРНЕМ
if (!isset($_SESSION['var_array'])) {
    $new = 'открыта еще одна вкладка</br>начата новая сессия';
    $array[0] = 'images';
    $_SESSION['var_array'] = $array;
    $dir = implode('/', $_SESSION['var_array']);
    $_SESSION['var array'] = $array;
      }else{
    $new = '';
    $array = $_SESSION['var array']; // запись сиссии в массив
    $dir = implode('/', $_SESSION['var_array']); //запись массива из сессии в переменную как строка элементов через разделитель(/)
}
echo '<h1><br>папка: /'.$dir.'</br></h1>';
//----------------------------------------------------------
// проверяем валидность папки (пока что таким способом)
    // изменено:
    //$dir_out = @opendir($dir) or die("Ошибка при открытии папки !!!");
    // на
    if (!@opendir($dir)) {
     session_unset(); // удаляем переменные сессии
    // перегружаем скриптом страницу
    echo '<script>location.reload(true);</script>';
    } else { // вывод о новой сессии 
    echo '<h3>'.$new.'<h3></br>
          <h1>папка: /'.$dir.'</h1>';
    }
    //
    // заполняем <select>
    $files = scandir($dir, 0);
    $select = '<form id = "sel_dir">';
// здесь в onchange много функций - в каждую потом можно пихнуть код
// наш главный upIncome()
    $select .= '<SELECT name ="sel" onchange="upIncome(); deleteall(this); log(this);">';
    $select .= '<option hidden="none">выбор из '.$dir.'__'.'</option>';
        for($i = 1; $i < count($files); $i++) {
            $infiles = $files[$i];
            $dir_out = $dir .'/'. $infiles;
// проверка объекта в рекурсии на то что он папка
                if (is_dir($dir_out)) {
                                        $select .= '<option name ="'.$infiles.'" value="'.$infiles.'">' . $infiles .'</option>';
                }
        }
    $select .= '</select>';
    $select .= '</form>';
    echo $select;
echo '</br>';
echo 'мы находимся в   /'.$dir.' =>' ;
echo '</br>';
//----------------------------------------------------------
//заимствовано и изменено
function printTree($level=1) {
  // Открываем каталог и выходим в случае ошибки.
  $d = @opendir('.');
  if (!$d) return;
  while (($e=readdir($d)) !== false) {
    // Игнорируем элементы .. и .
    if ($e=='.' || $e=='..') continue;
    // Нам нужны только подкаталоги.
    if (!@is_dir($e)) continue;
    // Печатаем пробелы, чтобы сместить вывод.
    for ($i=0; $i<$level; $i++) echo "   ";
    // Выводим текущий элемент.
    echo "$e\n";
    // Входим в текущий подкаталог и печатаем его
    if (!chdir($e)) continue;
    printTree($level+1);
    // Возвращаемся назад
    chdir("..");
    // Отправляем данные в браузер, чтобы избежать видимости зависания
    // для больших распечаток.
    flush();
  }
  closedir($d);
}
// Выводим остальной текст фиксированным шрифтом
echo "<pre>";
chdir(getcwd().'/'.$dir);
PrintTree();
echo "</pre>";
// оставляем сессию для записи
session_write_close();
?>
 
<!-- здесь вывод из out.php (но он нам не нужен)  -->
<div class="from-server"></div>
<!-- наша основная функция  -->
<script>
async function upIncome(){
        let response = await fetch('out.php',{
        method: 'POST',
        body: new FormData(document.querySelector('#sel_dir')),
        });
    ;
  log
    document.querySelector('.from-server').innerHTML = await response.text();
  location.reload(true);

    }
</script>

<!-- еще функция для onchange, то есть их может быть несколько,
эта должна записать в лог браузера выбранный элемент -->
<script>
function log(){ //  запись в лог браузера
  return e => {
    console.log(e.target.value)
  }
}
</script>

out.php

<?php
$dir = $_POST['sel']; // принимаем данные
session_start(); // сессия
//echo 'МОЖНО ВЫВЕСТИ, НО НАМ НЕ НУЖНО
//echo '<h1><br>папка: '.$dir.'</br></h1>';
// проверяем что сессия есть и пишем нужное в сессию
if (isset($_SESSION['var_array'])) { 
    $array = $_SESSION['var_array'];  // забираем из нее данные в массив
if ($dir == '..'){  // если выбрано '..'
    if ($array[1]){ // и присутсвует 2й элемент массива
        array_pop($array); // убираем последний элемент
        $_SESSION['var_array'] = $array; // и пишем в сессию
    }
} else { // иначе
    $array[] = $dir; //  добавляем новый элемент
    $_SESSION['var_array'] = $array; // и пишем в массив
    }
}
// сессию не закрываем
session_write_close();
?>
→ Ссылка