Я бы хотел, чтобы мой скрипт рекурсивно скандировал,
$files = scandir('/dir');
foreach($files as $file){
if(is_dir($file)){
echo '<li><label class="tree-toggler nav-header"><i class="fa fa-folder-o"></i>'.$file.'</label>';
$subfiles = scandir($rooturl.'/'.$file);
foreach($subfiles as $subfile){
// and so on and on and on
}
echo '<li>';
} else {
echo $file.'<br />';
}
}
Я хотел бы сделать это так, чтобы каждый найденный scandir dir был запущен другим scandir в папках, найденных в этом каталоге,
Так что dir 'A' содержит dir 1/2/3, теперь он должен использовать scandir (1), scandir (2), scandir (3) и так далее для каждого найденного dir.
Как я могу реализовать это легко, без копирования вставки кода снова и снова в каждом foreach?
EDIT: Поскольку ответы почти такие же, как я уже пробовал, я немного обновлю вопрос.
С помощью этого скрипта мне нужно создать список древовидных изображений. С текущими опубликованными скриптами происходит следующее echo'd:
/images/dir1/file1.png
/images/dir1/file2.png
/images/dir1/file3.png
/images/anotherfile.php
/data/uploads/avatar.jpg
/data/config.php
index.php
Мне действительно нужно:
<li><label>images</label>
<ul>
<li><label>dir1</label>
<ul>
<li>file1.png</li>
<li>file2.png</li>
<li>file3.png</li>
</ul>
</li>
<li>anotherfile.php</li>
</ul>
</li>
<li><label>data</label>
<ul>
<li><label>uploads</label>
<ul>
<li>avatar.jpg</li>
</ul>
</li>
<li>config.php</li>
</ul>
</li>
<li>index.php</li>
И так далее, Спасибо за уже опубликованные ответы!
Вы можете сканировать каталог рекурсивно таким образом, что цель - ваш самый верхний каталог:
function scanDir($target) {
if(is_dir($target)){
$files = glob( $target . '*', GLOB_MARK ); //GLOB_MARK adds a slash to directories returned
foreach( $files as $file )
{
scanDir( $file );
}
}
}
Вы можете легко адаптировать эту функцию для своей потребности. Например, если бы это использовало, чтобы удалить каталог и его содержимое, которое вы могли бы сделать:
function delete_files($target) {
if(is_dir($target)){
$files = glob( $target . '*', GLOB_MARK ); //GLOB_MARK adds a slash to directories returned
foreach( $files as $file )
{
delete_files( $file );
}
rmdir( $target );
} elseif(is_file($target)) {
unlink( $target );
}
Вы не можете делать это так, как вы делаете. Следующая функция получает рекурсивно все каталоги, подкаталоги настолько глубокие, насколько вы хотите, и их содержимое:
function assetsMap($source_dir, $directory_depth = 0, $hidden = FALSE)
{
if ($fp = @opendir($source_dir))
{
$filedata = array();
$new_depth = $directory_depth - 1;
$source_dir = rtrim($source_dir, '/').'/';
while (FALSE !== ($file = readdir($fp)))
{
// Remove '.', '..', and hidden files [optional]
if ( ! trim($file, '.') OR ($hidden == FALSE && $file[0] == '.'))
{
continue;
}
if (($directory_depth < 1 OR $new_depth > 0) && @is_dir($source_dir.$file))
{
$filedata[$file] = assetsMap($source_dir.$file.'/', $new_depth, $hidden);
}
else
{
$filedata[] = $file;
}
}
closedir($fp);
return $filedata;
}
echo 'can not open dir';
return FALSE;
}
Передайте свой путь к функции:
$path = 'elements/images/';
$filedata = assetsMap($path, $directory_depth = 5, $hidden = FALSE);
$ filedata - это массив со всеми созданными каталогами и подкаталогами с их содержимым. Эта функция позволяет сканировать структуру каталогов ($ directory_depth) настолько глубоко, насколько вы хотите, а также избавиться от всех скучных скрытых файлов (например, ".", "..")
Все, что вам нужно сделать, это использовать возвращаемый массив, который является полной древовидной структурой, чтобы упорядочить данные в вашем представлении по своему усмотрению.
То, что вы пытаетесь сделать, на самом деле является своего рода файловым менеджером, и, как вы знаете, есть множество из них в дикой природе, с открытым исходным кодом и бесплатно.
Надеюсь, это поможет вам, и я желаю вам веселого Рождества.
Я знаю, что это старый вопрос, но я написал версию этого, которая была более функциональной. Он не использует глобальное состояние и использует чистые функции, чтобы понять:
function scanAllDir($dir) {
$result = [];
foreach(scandir($dir) as $filename) {
if ($filename[0] === '.') continue;
$filePath = $dir . '/' . $filename;
if (is_dir($filePath)) {
foreach (scanAllDir($filePath) as $childFilename) {
$result[] = $filename . '/' . $childFilename;
}
} else {
$result[] = $filename;
}
}
return $result;
}
Хотя вопрос старый. Но мой ответ мог помочь людям, которые посещают этот вопрос.
Это рекурсивно сканирует директорию и дочерние каталоги и сохраняет результат в глобальной переменной.
global $file_info; // All the file paths will be pushed here
$file_info = array();
/**
*
* @function recursive_scan
* @description Recursively scans a folder and its child folders
* @param $path :: Path of the folder/file
*
* */
function recursive_scan($path){
global $file_info;
$path = rtrim($path, '/');
if(!is_dir($path)) $file_info[] = $path;
else {
$files = scandir($path);
foreach($files as $file) if($file != '.' && $file != '..') recursive_scan($path . '/' . $file);
}
}
recursive_scan('/var/www/html/wp-4.7.2/wp-content/plugins/site-backup');
print_r($file_info);
Создайте функцию сканирования и вызовите ее рекурсивно...
например:
<?php
function scandir_rec($root)
{
echo $root . PHP_EOL;
// When it a file or not a valid dir name
// Print it out and stop recusion
if (is_file($root) || !is_dir($root)) {
return;
}
// starts the scan
$dirs = scandir($root);
foreach ($dirs as $dir) {
if ($dir == '.' || $dir == '..') {
continue; // skip . and ..
}
$path = $root . '/' . $dir;
scandir_rec($path); // <--- CALL THE FUNCTION ITSELF TO DO THE SAME THING WITH SUB DIRS OR FILES.
}
}
// run it when needed
scandir_rec('./rootDir');
Вы можете много изменить эту функцию. Печать тега 'li' вместо PHP_EOL, например, для создания древовидного представления.
[РЕДАКТИРОВАТЬ]
<?php
function scandir_rec($root)
{
// if root is a file
if (is_file($root)) {
echo '<li>' . basename($root) . '</li>';
return;
}
if (!is_dir($root)) {
return;
}
$dirs = scandir($root);
foreach ($dirs as $dir) {
if ($dir == '.' || $dir == '..') {
continue;
}
$path = $root . '/' . $dir;
if (is_file($path)) {
// if file, create list item tag, and done.
echo '<li>' . $dir . '</li>';
} else if (is_dir($path)) {
// if dir, create list item with sub ul tag
echo '<li>';
echo '<label>' . $dir . '</label>';
echo '<ul>';
scandir_rec($path); // <--- then recursion
echo '</ul>';
echo '</li>';
}
}
}
// init call
$rootDir = 'rootDir';
echo '<ul>';
scandir_rec($rootDir);
echo '</ul>';