How to list all files in folders and sub-folders using scandir and display them as an option in select?
-
23-12-2019 - |
Domanda
I have a piece of code that I would like to modify to list all files in folders and sub-folders in the current path. I have found several possible solutions. I tried to implement them actually, but nothing seemed to work so I am not sure if they are actually working or not or it was just me implemented them wrong. Either way this is my current code:
<?php
$currentdir = 'C:/xampp/htdocs/test/'; //change to your directory
$dir = opendir($currentdir);
echo '<select name="workout">';
$file = preg_grep('/^([^.])/', scandir($dir));
while($file = readdir($dir))
{
if ($file != "." && $file != "..") {
echo "<option value='$file'>$file</option>";
}
else {
continue;
}
}
echo '</select>';
closedir($dir);
?>
Currently this code shows results:
$currentdir
Option1
Option2
Option3
SUB-FOLDER1
SUB-FOLDER2
Can someone help me and show me how to write/rewrite the code using existing one to display files from folders and other sub-folders to look something like this:
$currentdir
Option1
Option2
Option3
SUB-FOLDER1
Option1
Option2
Option3
SUB-FOLDER2
Option1
Option2
Option3
I became really desperate for a solution and thank you all in advance.
Soluzione
While the other answers are fine and correct, allow me to add my solution as well:
function dirToOptions($path = __DIR__, $level = 0) {
$items = scandir($path);
foreach($items as $item) {
// ignore items strating with a dot (= hidden or nav)
if (strpos($item, '.') === 0) {
continue;
}
$fullPath = $path . DIRECTORY_SEPARATOR . $item;
// add some whitespace to better mimic the file structure
$item = str_repeat(' ', $level * 3) . $item;
// file
if (is_file($fullPath)) {
echo "<option>$item</option>";
}
// dir
else if (is_dir($fullPath)) {
// immediatly close the optgroup to prevent (invalid) nested optgroups
echo "<optgroup label='$item'></optgroup>";
// recursive call to self to add the subitems
dirToOptions($fullPath, $level + 1);
}
}
}
echo '<select>';
dirToOptions();
echo '</select>';
It uses a recursive call to fetch the subitems. Note that I added some whitespace before each item to better mimic the file structure. Also I closed the optgroup
immediatly, to prevent ending up with nested optgroup
elements, which is invalid HTML.
Altri suggerimenti
Use DirectoryIterator
for looking into folder here is my approch
$di = new DirectoryIterator("/dir");
foreach($di as $dir){
if ($dir->isDot()) continue;
echo "<option value='", $dir->getFilename(), "'>", $dir->getFilename(), "</option>";
}
anyway for looking into sub directories as well
$ri = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
foreach($ri as $dir){
if ($dir->isDot()) continue;
echo "<option value='", $dir->getFilename(), "'>", $dir->getFilename(), "</option>";
}
In case you don't want to use above statement then this another alternative:
<?php
function listdir($currentdir){
$dir = opendir($currentdir);
$file = readdir($dir);
echo "<optgroup label='$currentdir'>";
do {
if (is_dir($currentdir."/".$file) && $file != "." && $file != ".."){
listdir($currentdir."/".$file);
echo $currentdir."/".$file;
} else if($file != "." && $file != "..") {
echo "<option value='$file'>$file</option>";
} else {
continue;
}
} while($file = readdir($dir));
echo "</optgroup>";
closedir($dir);
}
echo '<select name="workout">';
listdir('/var/www'); //change to your directory
echo '</select>';
?>
Find all the files and folders under a specified directory.
function scanDirAndSubdir($dir, &$out = []) {
$sun = scandir($dir);
foreach ($sun as $a => $filename) {
$way = realpath($dir . DIRECTORY_SEPARATOR . $filename);
if (!is_dir($way)) {
$out[] = $way;
} else if ($filename != "." && $filename != "..") {
scanDirAndSubdir($way, $out);
$out[] = $way;
}
}
return $out;
}
var_dump(scanDirAndSubdir('C:/xampp/htdocs/test/'));
Sample :
array (size=4)
0 => string 'C:/xampp/htdocs/test/text1.txt' (length=30)
1 => string 'C:/xampp/htdocs/test/text1.txt' (length=30)
2 => string 'C:/xampp/htdocs/test/subfolder1/text8.txt' (length=41)
3 => string 'C:/xampp/htdocs/test/subfolder4/text9.txt' (length=41)