• tutorials
  • php
  • using-a-recursive-function-to-traverse-a-directory-tree-page-2

Using a Recursive Function to Traverse a Directory Tree

Part - 2

In this tutorial the original directory listing script will become more user-friendly by enhancing it in a number of ways:
* A directory path for scanning can be conveniently set through the HTML form.
* All files in a subdirectory displayed first and sub-subdirectories it contains go after the files.
* A few CSS styles are added for a more pleasant view.
<?php // Define a recursive function: function list_dir($start) { static $level = 0; // Represents a level of depth of subdirectories below // the starting point, used for indenting the listing. // Get a list of files and directories // inside the specified path as an array: $contents = @scandir($start); // The @ symbol is the error suppression operator that stops // PHP from generating any errors should a problem occur during // a scan, cluttering up the screen. # ---------------------------------- # # --- ERROR MANAGEMENT DIVISION. --- # // Report if a problem occurred: if ($contents === false) { echo "\n"; echo "<b>Warning:</b> could not open the '$start' directory\n"; echo "The directory permissions are: " . substr(sprintf('%o', fileperms($start)), -4); echo "\n\n"; // Roll back to the previous level of indentation: $level--; // Quit the current invocation of the function: return; } // End of IF. # --- END OF ERROR MANAGEMENT DIVISION. --- # # ----------------------------------------- # // Initiate an array to store subdirectories of the current directory: $subdirs = []; // Loop over the files and directories: foreach ($contents as $item) { # ---------------------- # # --- DATA DIVISION. --- # // Quit iterations when the special entries // . (current directory) and .. (parent directory) // are encountered: if ($item === '.' || $item === '..') { continue; // Without this part the script would // go into an INFINITE LOOP. } // This time, instead of echoing spaces for indentation directly, // we save them into the '$indentation_str' variable to use later // in a couple of places. $indentation_str = ''; // Create indentation, based on the level of depth: for ($indent = 0; $indent <= $level; $indent++) { // In this example each indentation will consist of two space characters: $indentation_str .= ' '; } # --- DATA DIVISION. --- # # ---------------------- # # ----------------------------- # # --- PROCEDURE DIVISION 1. --- # if (!is_dir("$start/$item")) { // Echo files only: echo "<span class=\"dir-listing-indentation\">${indentation_str}</span><a href=\"$start/$item\" target=\"_blank\">$item</a>\n"; // Note that most likely you won't be able to follow those links, // unless your browser is Firefox and you have configured it // to allow opening local files on your computer. // This topic is outside of the scope of this tutorial. } else { // But save subdirectory paths in an array: $subdirs[] = "$start/$item"; } // End of IF-ELSE. # --- END OF PROCEDURE DIVISION 1. --- # # ------------------------------------ # } // End of FOREACH loop. # ----------------------------- # # --- PROCEDURE DIVISION 2. --- # // Loop through the array of collected subdirectories: foreach($subdirs as $subdir) { // Output the name of a subdirectory: echo "\n"; echo "${indentation_str} subdirectory: $subdir\n"; // Increment the static variable $level by 1 for indentation purposes: $level++; // Call the list_dir() function (from within its own code): echo list_dir($subdir); } // Roll back to the previous level of indentation: $level--; # --- END OF PROCEDURE DIVISION 2. --- # # ------------------------------------ # } // End of list_dir() function. /* ----------------------------- */ /* ----------------------------- */ ?> <!-- MAIN HTML CODE --> <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Directory Listing</title> <!-- Add a few CSS rules --> <style> .dir-listing-indentation { background: rgba(200,40,0,.15); margin-right: .4em; } </style> </head> <body> <form action="" method="get"> <label for="dir">Enter directory path</label> <input type="text" name="dir" id="dir" value="<?php // Make the input field "sticky": if (isset($_GET['dir'])) { echo $_GET['dir']; } ?>"> <input type="submit"> </form> <?php // when the form is submitted, determine a path to the directory // of interest (the starting-point) and start the listing by // calling the list_dir() recursive function: if ($_SERVER['REQUEST_METHOD'] === 'GET') { if (isset($_GET['dir'])) { $dir = $_GET['dir']; echo "<h1>Directory: $dir</h1>\n"; echo "<pre class=\"dir-listing\">"; list_dir($dir); echo "</pre>"; } } // End of submission IF. ?> </body> </html> <!-- END OF MAIN HTML CODE -->
This page was last updated on January 28, 2021
No comments have been posted so far
Leave a Comment