6

I have a tree of directories, sub-directories, and files (in some but not all the directories). Here's an example of the whole tree:

/food
/food/drinks
/food/drinks/water.html
/food/drinks/milk.html
/food/drinks/soda.html
/food/entrees
/food/entrees/hot
/food/entrees/hot/hamburger.html
/food/entrees/hot/pizza.html
/food/entrees/cold
/food/entrees/cold/icecream.html
/food/entrees/cold/salad.html
/cosmetics
/cosmetics/perfume
/cosmetics/perfume/chic.html
/cosmetics/perfume/polo.html
/cosmetics/perfume/lust.html
/cosmetics/lipstick
/cosmetics/lipstick/colors
/cosmetics/lipstick/colors/red.html
/cosmetics/lipstick/colors/pink.html
/cosmetics/lipstick/colors/purple.html

OK, From a php script in the '/' directory, I want to recurse or traverse this directory tree and print the tree like this:

<ul>
  <li>food</li>
    <ul>
      <li>drinks</li>
        <ul>
          <li>water.html</li>
          <li>milk.html</li>
          <li>soda.html</li>
        </ul>
      <li>entrees</li>
        <ul>
          <li>hot</li>
            <ul>
              <li>hamburger.html</li>
              <li>pizza.html</li>
            </ul>
          <li>cold</li>
            <ul>
              <li>icecream.html</li>
              <li>salad.html</li>
            </ul>      
        </ul>
    </ul>
  <li>cosmetics</li>
    <ul>
      <li>perfume</li>
        <ul>
          <li>chic.html</li>
          <li>polo.html</li>
          <li>lust.html</li>
        </ul>
      <li>lipstick</li>
        <ul>
          <li>colors</li>
            <ul>
              <li>red.html</li>
              <li>pink.html</li>
              <li>purple.html</li>
            </ul>
        </ul>
    </ul>
</ul>
1
  • no idea why moderators have closed this. the question is super clear. they are 3-4 solutions to this, some of them have not been presented yet. i responded to something similar here: stackoverflow.com/a/48550987/4481831 Commented Jan 31, 2018 at 20:45

4 Answers 4

8

What I think you need here is the RecursiveDirectoryIterator from the PHP Standard Library (SPL)

You can then write something similar to the below:

function iterateDirectory($i)
{
    echo '<ul>';
    foreach ($i as $path) {
        if ($path->isDir())
        {
            echo '<li>';
            iterateDirectory($path);
            echo '</li>';
        }
        else
        {
            echo '<li>'.$path.'</li>';
        }
    }
    echo '</ul>';
}

$dir = '/food';
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));

iterateDirectory($iterator);
Sign up to request clarification or add additional context in comments.

4 Comments

using $dir = $_SERVER['DOCUMENT_ROOT'].'/test'; as my starting directory... This outputs nothing for me.
Yup, I see the problem. I was defining a type for $i in the iterateDirectory function, which was throwing an exception. Try it now and see how you get on
This script does not produce the html example, provided in the OP's question. The code does not show folders.. And the ul to li to ul to li listing order is very messed up.
Here's a working example: stackoverflow.com/a/10780023/991068
7

To get you started, it need the following functions to work:

  • opendir() to get the directory handler
  • readdir() to read it's content
  • is_dir() to determine if current value taken from readdir() is directory or files

To glue it all together, you will need:

Here's how it is after all resources above is glued:

<?php

function read_dir_content($parent_dir, $depth = 0){
    $str_result = "";

    $str_result .= "<li>". dirname($parent_dir) ."</li>";
    $str_result .= "<ul>";
    if ($handle = opendir($parent_dir)) 
    {
        while (false !== ($file = readdir($handle)))
        {
            if(in_array($file, array('.', '..'))) continue;
            if( is_dir($parent_dir . "/" . $file) ){
                $str_result .= "<li>" . read_dir_content($parent_dir . "/" . $file, $depth++) . "</li>";
            }
            $str_result .= "<li>{$file}</li>";
        }
        closedir($handle);
    }
    $str_result .= "</ul>";


    return $str_result;
}


echo "<ul>".read_dir_content("d:/movies/")."</ul>";

3 Comments

This is the only solution so far that does something similar to what I want, except, in the ULs, it embeds parent directories in child directories in a weird way
this code is pretty straightforward. Just change some lines and you'll get what you really want. See the updated code.
This answer, while the HTML part needs tweaking for better readability.. Is the correct answer for the OP's question and deserves to be marked as correct! Thank you for the code. OT: Who was the moron, who actually downvoted this?
4

I use this to have all files in a dir :

function tree($path, $exclude = array()) {
    $files = array();
    foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $splfileinfo) {
        if (!in_array(basename($splfileinfo), $exclude)) {
            $files[] = str_replace($path, '', '' . $splfileinfo);
        }
    }
    return $files;
}

Comments

1

Hope this function will help you to get done your work.

/*
     * Retern the file list which include in the given directory
     *
     * @param String $dirpath : Path to the directory
     * 
     * @access public
     * 
     * @return Array
     */
    function getFileList($dirpath)
    {
        $filelist = array();
        if ($handle = opendir(dirname ($dirpath))) 
        {
           while (false !== ($file = readdir($handle)))
              {
                    $filelist[] = $file;
              }
            closedir($handle);
        }

        return $filelist;
    }

2 Comments

I getFileList($_SERVER['DOCUMENT_ROOT'].'/test') which is the root directory I want to traverse, and then I print_r the return array, and I get the contents of only the $_SERVER['DOCUMENT_ROOT'] directory..
You can call the function recursively until you get no files.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.