2015-12-09 2 views
0

Я хотел бы мой сценарий ScanDir рекурсивно,PHP ScanDir рекурсивно

$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, он запускает другой ScanDir на папки, которые имеют были найдены в пределах этого каталога,

Так что dir 'A' содержит dir 1/2/3, теперь он должен быть scandir (1), scandir (2), scandir (3) и т. д. для каждого найденного каталога.

Как я могу легко реализовать это без копирования, вставляя код снова и снова в каждый файл 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> 

И так далее, спасибо за уже размещены ответы!

+0

ряда рекурсивных основы программирования, is_dir ($ файл) должен быть is_dir («/ реж/$ файла») – Jack

+0

использовать рекурсию ... –

+0

проверить набор классов «recursiveIterator» - http://php.net/manual/en/class.recursivedirectoryiterator.php – RamRaider

ответ

1

Вы можете сканировать каталог рекурсивно, таким образом, цель ваш самый верхний каталог:

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) настолько глубоко, насколько вы хотите, а также избавиться от всех скучных скрытых файлов (например, «.», «..»)

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

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

Я надеюсь, что это поможет вам, и я желаю вам веселого Рождества.

+0

Спасибо за ответ. Однако я не могу заставить это работать так, как мне это нужно, я обновил свой первоначальный вопрос для лучшего объяснения :) – Sjef92

+0

I определенно попробуют это, я не проверял сценарии с открытым исходным кодом для этого, так как в основном вам приходится стирать, как 70% их построений, чтобы соответствовать вашим собственным скриптам/шаблонам/страницам. Благодарим вас за ответы и счастливое Рождество для себя! :) – Sjef92

1

Создание функции сканирования и назовите его recursively ...

например:

<?php 

    function scandir_rec($root) 
    { 
     echo $root . PHP_EOL; 
     // When it's 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, например, для создания древовидного представления.

[EDIT]

<?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>'; 
+0

Спасибо за ответ. Однако я не могу заставить это работать так, как мне это нужно, я обновил свой первоначальный вопрос для лучшего объяснения :) – Sjef92

0

Хотя вопрос стар. Но мой ответ мог помочь людям, которые посещают этот вопрос.

Это рекурсивно сканирует директорию и дочерние каталоги и сохраняет результат в глобальной переменной.

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); 
0

Я знаю, что это старый вопрос, но я написал версию этого, которая была более функциональной. Он не использует глобальное состояние и использует чистые функции, чтобы понять вещи:

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; 
} 
Смежные вопросы