{"id":3181,"date":"2014-01-26T18:19:13","date_gmt":"2014-01-26T23:19:13","guid":{"rendered":"http:\/\/www.lonhosford.com\/lonblog\/?p=3181"},"modified":"2021-03-29T20:28:00","modified_gmt":"2021-03-30T01:28:00","slug":"how-to-traverse-file-directories-recursively-with-php-recursivedirectoryiterator-class","status":"publish","type":"post","link":"https:\/\/www.lonhosford.com\/lonblog\/2014\/01\/26\/how-to-traverse-file-directories-recursively-with-php-recursivedirectoryiterator-class\/","title":{"rendered":"How to Recursively Traverse File Directories with PHP RecursiveDirectoryIterator"},"content":{"rendered":"<a href='https:\/\/www.lonhosford.com\/lonblog?bha=true&#038;user=alhecommerce&#038;id=shortcode\/LonBlogGeneral'><img class='none' src='https:\/\/img.bluehost.com\/\/468x60\/bh_468x60_01.gif' \/><\/a>\n<div id=\"fb-root\"><\/div>\n<p><script src=\"https:\/\/connect.facebook.net\/en_US\/all.js#appId=105467682877384&amp;xfbml=1\"><\/script><!-- Place this tag where you want the +1 button to render --><br \/>\nBy Lon Hosford<br \/>\nYou can avoid writing recursive function to traverse through tree structures like you server file system. PHP has several <code>Iterator<\/code> classes starting with version 5. <img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-medium wp-image-3182\" src=\"https:\/\/www.lonhosford.com\/lonblog\/wp-content\/uploads\/2014\/01\/php_recursive_directory_iterator-300x181.png\" alt=\"PHP Logo with  RecursiveDirectoryIterator\" width=\"300\" height=\"181\" srcset=\"https:\/\/www.lonhosford.com\/lonblog\/wp-content\/uploads\/2014\/01\/php_recursive_directory_iterator-300x181.png 300w, https:\/\/www.lonhosford.com\/lonblog\/wp-content\/uploads\/2014\/01\/php_recursive_directory_iterator.png 900w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>In this article we will look at the <code>RecursiveDirectoryIterator<\/code> class. We will build a utility function to use the <code>RecursiveDirectoryIterator<\/code> class to provide a text listing of the path and file names in one or more directories.<\/p>\n<p>Although we are just displaying paths to the files, you can also access the file information such as modification date, creation date, size, permissions and a variety of properties through the parent classes of <code>RecursiveDirectoryIterator<\/code>. Those classes include in order of inheritance: <code>FilesystemIterator<\/code>, <code>DirectoryIterator<\/code> and <code>SplFileInfo<\/code>. <code>SplFileInfo<\/code> provides many of the global file functions in PHP such as <code>isDir<\/code>, <code>is_readable<\/code> <code>is_writeable<\/code> and <code>is_real<\/code> for example.<\/p>\n<div style=\"text-align: center;\"><a href=\"http:\/\/click.linksynergy.com\/link?id=A1q8CHNXgAc&amp;offerid=323057.84900&amp;type=2&amp;murl=https%3A%2F%2Fwww.udemy.com%2Fphp-search-form%2F\" target=\"new\" rel=\"noopener\"><img decoding=\"async\" src=\"https:\/\/udemyimages-a.akamaihd.net\/course\/480x270\/84900_2c11_10.jpg\" border=\"0\" \/><\/a><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/ad.linksynergy.com\/fs-bin\/show?id=A1q8CHNXgAc&amp;bids=323057.84900&amp;type=2&amp;subid=0\" width=\"1\" height=\"1\" border=\"0\" \/><\/div>\n<p>Source Files: <a title=\"Source File Download Link\" href=\"http:\/\/www.lonhosford.com\/lonblog\/wp-content\/uploads\/php\/php_recursive_directory_iterator.zip\">Download<\/a><\/p>\n<p>Video Tutorial:<\/p>\n<p>[iframe https:\/\/www.youtube.com\/embed\/jtqVJ3-95m4 640 360]<\/p>\n<div style=\"font-size: 1.1em; font-weight: bold;\">The User Interface &#8211; <code>test_debug_dir_list.php<\/code><\/div>\n<p>There is a simple hybrid HTML PHP script, <code>test_debug_dir_list.php<\/code>, to demonstrate. It has five tests using a customized function for <code>RecursiveDirectoryIterator<\/code>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3197\" src=\"https:\/\/www.lonhosford.com\/lonblog\/wp-content\/uploads\/2014\/01\/test_debug_start.png\" alt=\"test_debug_dir_list.php in browser no links chosen\" width=\"610\" height=\"305\" srcset=\"https:\/\/www.lonhosford.com\/lonblog\/wp-content\/uploads\/2014\/01\/test_debug_start.png 610w, https:\/\/www.lonhosford.com\/lonblog\/wp-content\/uploads\/2014\/01\/test_debug_start-300x150.png 300w\" sizes=\"auto, (max-width: 610px) 100vw, 610px\" \/><br \/>\nThis is the first test showing all the file and directories in the folder that <code>test_debug_dir_list.php<\/code> is in.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3194\" src=\"https:\/\/www.lonhosford.com\/lonblog\/wp-content\/uploads\/2014\/01\/test_debug_current_dir.png\" alt=\"test_debug_current_dir in browser first test link chosen\" width=\"607\" height=\"403\" srcset=\"https:\/\/www.lonhosford.com\/lonblog\/wp-content\/uploads\/2014\/01\/test_debug_current_dir.png 607w, https:\/\/www.lonhosford.com\/lonblog\/wp-content\/uploads\/2014\/01\/test_debug_current_dir-300x199.png 300w\" sizes=\"auto, (max-width: 607px) 100vw, 607px\" \/><\/p>\n<p>[ad name=&#8221;Google Adsense&#8221;]<\/p>\n<p>The second test showing all the file and directories in the folder that <code>test_debug_dir_list.php<\/code> and of all its child directories.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3196\" src=\"https:\/\/www.lonhosford.com\/lonblog\/wp-content\/uploads\/2014\/01\/test_debug_parent_dir.png\" alt=\"test_debug_current_dir_1 in browser second test link chosen\" width=\"605\" height=\"420\" srcset=\"https:\/\/www.lonhosford.com\/lonblog\/wp-content\/uploads\/2014\/01\/test_debug_parent_dir.png 605w, https:\/\/www.lonhosford.com\/lonblog\/wp-content\/uploads\/2014\/01\/test_debug_parent_dir-300x208.png 300w\" sizes=\"auto, (max-width: 605px) 100vw, 605px\" \/><\/p>\n<p>The third links shows the files and directories of the parent directory for <code>test_debug_dir_list.php<\/code>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3196\" src=\"https:\/\/www.lonhosford.com\/lonblog\/wp-content\/uploads\/2014\/01\/test_debug_parent_dir.png\" alt=\"test_debug_parent_dir in browser third test link chosen\" width=\"605\" height=\"420\" srcset=\"https:\/\/www.lonhosford.com\/lonblog\/wp-content\/uploads\/2014\/01\/test_debug_parent_dir.png 605w, https:\/\/www.lonhosford.com\/lonblog\/wp-content\/uploads\/2014\/01\/test_debug_parent_dir-300x208.png 300w\" sizes=\"auto, (max-width: 605px) 100vw, 605px\" \/><\/p>\n<p>This fourth test link is like the third but includes the first level of children directories for the parent directory.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3195\" src=\"https:\/\/www.lonhosford.com\/lonblog\/wp-content\/uploads\/2014\/01\/test_debug_parent_dir_1.png\" alt=\"test_debug_parent_dir_1 in browser third test link chosen\" width=\"599\" height=\"508\" srcset=\"https:\/\/www.lonhosford.com\/lonblog\/wp-content\/uploads\/2014\/01\/test_debug_parent_dir_1.png 599w, https:\/\/www.lonhosford.com\/lonblog\/wp-content\/uploads\/2014\/01\/test_debug_parent_dir_1-300x254.png 300w\" sizes=\"auto, (max-width: 599px) 100vw, 599px\" \/><\/p>\n<p>This fifth link test one more child directory level than the fourth.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3193\" src=\"https:\/\/www.lonhosford.com\/lonblog\/wp-content\/uploads\/2014\/01\/test_debug_current_dir_2.png\" alt=\"test_debug_parent_dir_2 in browser third test link chosen\" width=\"607\" height=\"573\" srcset=\"https:\/\/www.lonhosford.com\/lonblog\/wp-content\/uploads\/2014\/01\/test_debug_current_dir_2.png 607w, https:\/\/www.lonhosford.com\/lonblog\/wp-content\/uploads\/2014\/01\/test_debug_current_dir_2-300x283.png 300w\" sizes=\"auto, (max-width: 607px) 100vw, 607px\" \/><\/p>\n<div style=\"font-size: 1.1em; font-weight: bold;\">Custom Function <code>debug_dir_list<\/code> Using <code>RecursiveDirectoryIterator<\/code><\/div>\n<p>The function parameters on line 17 are the depth levels for recursing file system directories and the starting file system directory.<\/p>\n<p>The default file system directory is the running script that might include <strong>debug_utils.inc.php<\/strong> contain our function. You can use the standard file system notation to express parent directories and paths.<\/p>\n<p>The depth levels are the exact values for the <code>RecursiveIteratorIterator<\/code> class instance created on line 23. A negative one recurses to the last lowest level. Be careful with that on a big file system where the second argument is the root or near it. The <code>debug_dir_list<\/code> default value is zero which confines the <code>RecursiveIteratorIterator<\/code> instance to the starting files system directory.<\/p>\n<p><strong>debug_utils.inc.php &#8211; parameters<\/strong><\/p>\n<pre><pre class=\"brush: php; collapse: false; first-line: 17; title: ; notranslate\" title=\"\">\nfunction debug_dir_list($dir_recurse_depth = 0, $dir_list_root = '.'){\n<\/pre>\n<p>Lines 19 to 21 creates the <code>RecursiveDirectoryIterator<\/code> instance. It has to arguments. The first, on line 20, is the starting directory and we use the <code>debug_dir_list<\/code> function&#8217;s second parameter without change. The second <code>RecursiveDirectoryIterator<\/code> instance parameter is a set of flags. We are using the flag to suppress showing the single and double dot files.<\/p>\n<p><strong>debug_utils.inc.php &#8211; The <code>RecursiveDirectoryIterator<\/code> Instance<\/strong><\/p>\n<pre><pre class=\"brush: php; collapse: false; first-line: 18; title: ; notranslate\" title=\"\">\n\t\/\/ Create a recursive file system directory iterator.\n\t$dir_iter = new RecursiveDirectoryIterator(\n\t\t$dir_list_root,\n\t\tRecursiveDirectoryIterator::SKIP_DOTS) ;\/\/ Skips dot files (. and ..)\n<\/pre>\n<p>Lines 23 to 27 create the <code>RecursiveIteratorIterator<\/code> class instance. Its first parameter on line 24 requires a class with a traversal iterator class and <code>RecursiveDirectoryIterator<\/code> implements the <code>RecursiveIterator<\/code> interface to meet that requirement.<\/p>\n<p>The second argument on line 25 for the <code>RecursiveIteratorIterator<\/code> constructor is called mode. There are three modes that are constants to the class.<\/p>\n<ul>\n<li><code>RecursiveIteratorIterator::LEAVES_ONLY<\/code> &#8211; The default. Lists only leaves in iteration.<\/li>\n<li><code>RecursiveIteratorIterator::SELF_FIRST<\/code> &#8211; Lists leaves and parents in iteration with parents coming first.<\/li>\n<li><code>RecursiveIteratorIterator::CHILD_FIRST<\/code> &#8211; Lists leaves and parents in iteration with leaves coming first.<\/li>\n<\/ul>\n<p>The <code>RecursiveIteratorIterator<\/code> constructor&#8217;s third argument on line 26 is called modes. It is optional and currently only has its own <code>RecursiveIteratorIterator::CATCH_GET_CHILD<\/code> as a possible value which will then ignore exceptions thrown such as denied file permissions.<\/p>\n<p>Line 29 passed the recursion depth through the <code>RecursiveIteratorIterator<\/code> class <code>setMaxDepth<\/code> method. Here to the <code>debug_dir_list<\/code> function&#8217;s parameter is passed unchanged.<\/p>\n<p><strong>debug_utils.inc.php &#8211; The <code>RecursiveIteratorIterator<\/code> Instance<\/strong><\/p>\n<pre><pre class=\"brush: php; collapse: false; first-line: 22; title: ; notranslate\" title=\"\">\n\t\/\/ Create a recursive iterator.\n\t$iter = new RecursiveIteratorIterator(\n\t\t$dir_iter,\n\t\tRecursiveIteratorIterator::SELF_FIRST, \/\/ Lists leaves and parents in iteration with parents coming first.\n\t\tRecursiveIteratorIterator::CATCH_GET_CHILD \/\/ Ignore exceptions such as &quot;Permission denied&quot;\n\t\t);\n\t\/\/ The maximum recursive path.\n\t$iter-&amp;amp;gt;setMaxDepth($dir_recurse_depth);\n<\/pre>\n<p>The rest of the function uses the <code>RecursiveIteratorIterator<\/code> to iterate its objects which have a base class of <code>SplFileInfo<\/code>. These objects resolve as the path string. But also you can see on line 33, they have the method <code>isDir<\/code> which is like the standalone <code>is_file<\/code> function. If you explore the <code>SplFileInfo<\/code> class you can see all the other methods for file system objects. Line 31 is really just adding for visual purposes a trailing slash to objects that are a directory and not the starting directory.<\/p>\n<p>Line 34 pushes that <code>$path<\/code> string onto the <code>$paths<\/code> array which is returned from the <code>debug_dir_list<\/code> function.<\/p>\n<p><strong>debug_utils.inc.php<\/strong><\/p>\n<pre><pre class=\"brush: php; collapse: false; first-line: 30; title: ; notranslate\" title=\"\">\n\t\/\/ List of paths Include current paths\n\t$path = array($dir_list_root);\n\tforeach ($iter as $path =&amp;amp;gt; $dir) {\n\t\tif ($dir_recurse_depth == 0 &amp;amp;amp;&amp;amp;amp; $dir-&amp;amp;gt;isDir()) $path .= &quot;\/&quot;;\n\t\t$paths&#x5B;] = substr($path,2);\n\t}\n\treturn $paths;\n<\/pre>\n<p><strong>debug_utils.inc.php &#8211; full listing<\/strong><\/p>\n<pre><pre class=\"brush: php; collapse: true; light: false; title: ; toolbar: true; notranslate\" title=\"\">\n&amp;amp;lt;?php\n\/**\n *\tUtilitites to help in debugging.\n *\n *\t@author Lon Hosford\n *\t@link www.lonhosford.com\n*\/\n\/**\n *\tCreate an array of files and directory names, Requires PHP 5 &amp;amp;gt;= 5.3.1.\n *\n *\tDirectories without contents have a slash appended or at the $dir_recurse_depth regardless if they have contents. Hidden files and folders are included.\n *\t@link http:\/\/stackoverflow.com\/questions\/14304935\/php-listing-all-directories-and-sub-directories-recursively-in-drop-down-menu This code is based on this Stackoverflow post.\n *\t@param int $dir_recurse_depth recurse depth. 0 for $dir_list_root. Add 1 for each child level.  -1 is used for any depth.\n *\t@param string $dir_list_root recurse depth. Starting folder path. Files in this directory are included. Default is current directory.\n *\t@return string&#x5B;] List of folders and files found.\n *\/\nfunction debug_dir_list($dir_recurse_depth = 0, $dir_list_root = '.'){\n\t\/\/ Create a recursive file system directory iterator.\n\t$dir_iter = new RecursiveDirectoryIterator(\n\t\t$dir_list_root,\n\t\tRecursiveDirectoryIterator::SKIP_DOTS) ;\/\/ Skips dot files (. and ..)\n\t\/\/ Create a recursive iterator.\n\t$iter = new RecursiveIteratorIterator(\n\t\t$dir_iter,\n\t\tRecursiveIteratorIterator::SELF_FIRST, \/\/ Lists leaves and parents in iteration with parents coming first.\n\t\tRecursiveIteratorIterator::CATCH_GET_CHILD \/\/ Ignore exceptions such as &quot;Permission denied&quot;\n\t\t);\n\t\/\/ The maximum recursive path.\n\t$iter-&amp;amp;gt;setMaxDepth($dir_recurse_depth);\n\t\/\/ List of paths Include current paths\n\t$path = array($dir_list_root);\n\tforeach ($iter as $path =&amp;amp;gt; $dir) {\n\t\tif ($dir_recurse_depth == 0 &amp;amp;amp;&amp;amp;amp; $dir-&amp;amp;gt;isDir()) $path .= &quot;\/&quot;;\n\t\t$paths&#x5B;] = substr($path,2);\n\t}\n\treturn $paths;\n}\n?&amp;amp;gt;\n<\/pre>\n<div style=\"font-size: 1.1em; font-weight: bold;\">The User Interface &#8211; Exploring the source of <code>test_debug_dir_list.php<\/code><\/div>\n<p>For the UI script line 10 imports our <code>debug_dir_list<\/code> function.<\/p>\n<p><strong>test_debug_dir_list.php<\/strong><\/p>\n<pre><pre class=\"brush: php; collapse: false; first-line: 10; title: ; notranslate\" title=\"\">\ninclude_once &quot;debug_utils.inc.php&quot;;\n<\/pre>\n<p>Line 32 and lines 35 to 40 provide a url link back to <code>test_debug_dir_list.php<\/code>. Lines 35 to 40 provide a NVP (Name Value Pair) for the URL query and line 32 omits that. The NVP name is <code>debug-action<\/code> and the values <code>current_dir<\/code>, <code>current_dir_1<\/code>, <code>parent_dir<\/code>, <code>parent_dir_1<\/code> and <code>parent_dir_2<\/code>.<\/p>\n<p><strong>test_debug_dir_list.php<\/strong><\/p>\n<pre><pre class=\"brush: php; collapse: false; first-line: 32; html-script: true; title: ; notranslate\" title=\"\">\n&amp;amp;lt;h3&amp;amp;gt;debug_dir_list($dir_recurse_depth = 0, $dir_list_root = '.')&amp;amp;lt;\/h3&amp;amp;gt;\n&amp;amp;lt;ol class = 'mono-space'&amp;amp;gt;\n\t&amp;amp;lt;li&amp;amp;gt;&amp;amp;lt;a href=&quot;&amp;amp;lt;?php echo $_SERVER&#x5B;'PHP_SELF'] . '?debug-action=current_dir';?&amp;amp;gt;&quot;&amp;amp;gt;Run&amp;amp;lt;\/a&amp;amp;gt; - List Current Directory - debug_dir_list()&amp;amp;lt;\/li&amp;amp;gt;\n\t&amp;amp;lt;li&amp;amp;gt;&amp;amp;lt;a href=&quot;&amp;amp;lt;?php echo $_SERVER&#x5B;'PHP_SELF'] . '?debug-action=current_dir_1';?&amp;amp;gt;&quot;&amp;amp;gt;Run&amp;amp;lt;\/a&amp;amp;gt; - List Current Directory + Children(1) - debug_dir_list(1)&amp;amp;lt;\/li&amp;amp;gt;\n\t&amp;amp;lt;li&amp;amp;gt;&amp;amp;lt;a href=&quot;&amp;amp;lt;?php echo $_SERVER&#x5B;'PHP_SELF'] . '?debug-action=parent_dir';?&amp;amp;gt;&quot;&amp;amp;gt;Run&amp;amp;lt;\/a&amp;amp;gt; - List Parent Directory  + Children(0) - debug_dir_list(0, &quot;..\/&quot;)&amp;amp;lt;\/li&amp;amp;gt;\n\t&amp;amp;lt;li&amp;amp;gt;&amp;amp;lt;a href=&quot;&amp;amp;lt;?php echo $_SERVER&#x5B;'PHP_SELF'] . '?debug-action=parent_dir_1';?&amp;amp;gt;&quot;&amp;amp;gt;Run&amp;amp;lt;\/a&amp;amp;gt; - List Parent Directory + Children(1) - debug_dir_list(1, &quot;..\/&quot;)&amp;amp;lt;\/li&amp;amp;gt;\n\t&amp;amp;lt;li&amp;amp;gt;&amp;amp;lt;a href=&quot;&amp;amp;lt;?php echo $_SERVER&#x5B;'PHP_SELF'] . '?debug-action=parent_dir_2';?&amp;amp;gt;&quot;&amp;amp;gt;Run&amp;amp;lt;\/a&amp;amp;gt; - List Parent Directory + Children(2) - debug_dir_list(2, &quot;..\/&quot;)&amp;amp;lt;\/li&amp;amp;gt;\n&amp;amp;lt;\/ol&amp;amp;gt;\n<\/pre>\n<p>Lines 44 to 48 interrogate the super global <code>$_GET<\/code> variable for the <code>debug-action<\/code> key and sets the <code>$get_action<\/code> variable either as an empty string or the value in the <code>$_GET['debug-action']<\/code> variable. There is no need to sanitize here as this is for internal development and testing and not a production script.<\/p>\n<p><strong>test_debug_dir_list.php<\/strong><\/p>\n<pre><pre class=\"brush: php; collapse: false; first-line: 44; html-script: false; title: ; notranslate\" title=\"\">\n&amp;amp;lt;?php\nif ( !isset($_GET&#x5B;&quot;debug-action&quot;]) ){\n\t$get_action = &quot;&quot;;\n}else{\n\t$get_action = $_GET&#x5B;&quot;debug-action&quot;];\n}\n<\/pre>\n<p>Lines 52 to 68 a switch block sets out each of the <code>debug-action<\/code> values and echoes the results of the <code>debug_dir_list<\/code> function with parameters to meet the desired results.<\/p>\n<p><strong>test_debug_dir_list.php<\/strong><\/p>\n<pre><pre class=\"brush: php; collapse: false; first-line: 52; html-script: false; title: ; notranslate\" title=\"\">\nswitch($get_action){\n\tcase 'current_dir':\n\t\techo &quot;File list: &quot; . print_r(debug_dir_list(), true);\n\tbreak;\n\tcase 'current_dir_1':\n\t\techo &quot;File list: &quot; . print_r(debug_dir_list(1), true);\n\tbreak;\n\tcase 'parent_dir':\n\t\techo &quot;File list : &quot; . print_r(debug_dir_list(0, &quot;..\/&quot;), true);\n\tbreak;\n\tcase 'parent_dir_1':\n\t\techo &quot;File list: &quot; . print_r(debug_dir_list(1, &quot;..\/&quot;), true);\n\tbreak;\n\tcase 'parent_dir_2':\n\t\techo &quot;File list: &quot; . print_r(debug_dir_list(2, &quot;..\/&quot;), true);\n\tbreak;\n}\n<\/pre>\n<p>Worth a mention are lines 49 to 51. They help debug the debugging. The file name is helpful on line 49 when you are bleary eyed and not sure which testing script you are running. The basename function passed the magic constant __FILE__ provides the file name of this script. In face you might want to add a line use display the magic constant __FILE__. Testing scripts can get spread around and copied when the coding battle to finish gets wild.<\/p>\n<p>Along with that heat of the battle information is the PHP version in front of your eyes. Line 50 does that. There is always the situation that a &#8220;temporary&#8221; server is needed to run some tests and no one bothers to check the PHP version installed. The <code>phpversion<\/code> function is just the ticket.<\/p>\n<p>Then to check this debugging program is passing the expected <code>debug-action<\/code> value, we throw that out on line 51.<\/p>\n<p><strong>test_debug_dir_list.php<\/strong><\/p>\n<pre><pre class=\"brush: php; collapse: false; first-line: 49; html-script: false; title: ; notranslate\" title=\"\">\necho basename(__FILE__) . &quot;\\n&quot;;\necho &quot;PHP version: &quot; . phpversion() . &quot;\\n&quot;;\necho &quot;debug-action=&quot; . $get_action . &quot;\\n&quot;;\n<\/pre>\n<p><strong>test_debug_dir_list.php &#8211; full listing<\/strong><\/p>\n<pre><pre class=\"brush: php; collapse: true; html-script: true; light: false; title: ; toolbar: true; notranslate\" title=\"\">\n&amp;amp;lt;?php\n\/**\n *\tThe debugging dashboard for testing and development.\n *\n *  @author Lon Hosford\n *  @link www.lonhosford.com\n *\t@copyright 2014 Alonzo Hosford\n *  @license GPL\n*\/\ninclude_once &quot;debug_utils.inc.php&quot;;\n?&amp;amp;gt;\n&amp;amp;lt;!doctype html&amp;amp;gt;\n&amp;amp;lt;html&amp;amp;gt;\n&amp;amp;lt;head&amp;amp;gt;\n\t&amp;amp;lt;meta charset=&quot;UTF-8&quot;&amp;amp;gt;\n\t&amp;amp;lt;title&amp;amp;gt;Testing and Debugging Dashboard | lonhosford.com&amp;amp;lt;\/title&amp;amp;gt;\n\t&amp;amp;lt;style&amp;amp;gt;\n\tbody{ font-family:&quot;Gill Sans&quot;, &quot;Gill Sans MT&quot;, &quot;Myriad Pro&quot;, &quot;DejaVu Sans Condensed&quot;, Helvetica, Arial, sans-serif}\n\tpre {\n\t white-space: pre-wrap;       \/* css-3 *\/\n\t white-space: -moz-pre-wrap;  \/* Mozilla, since 1999 *\/\n\t white-space: -pre-wrap;      \/* Opera 4-6 *\/\n\t white-space: -o-pre-wrap;    \/* Opera 7 *\/\n\t word-wrap: break-word;       \/* Internet Explorer 5.5+ *\/\n\t}\n\t.mono-space{font-family:monospace;}\n\ttable,td {border:solid 1px #000;}\n\t&amp;amp;lt;\/style&amp;amp;gt;\n&amp;amp;lt;\/head&amp;amp;gt;\n&amp;amp;lt;body&amp;amp;gt;\n&amp;amp;lt;h2&amp;amp;gt;Testing and Debugging Dashboard&amp;amp;lt;\/h2&amp;amp;gt;\n&amp;amp;lt;h4&amp;amp;gt;&amp;amp;lt;a href=&quot;&amp;amp;lt;?php echo $_SERVER&#x5B;'PHP_SELF'];?&amp;amp;gt;&quot;&amp;amp;gt;&amp;amp;lt;?php echo basename(__FILE__);?&amp;amp;gt;&amp;amp;lt;\/a&amp;amp;gt;&amp;amp;lt;\/h4&amp;amp;gt;\n&amp;amp;lt;h3&amp;amp;gt;debug_dir_list($dir_recurse_depth = 0, $dir_list_root = '.')&amp;amp;lt;\/h3&amp;amp;gt;\n&amp;amp;lt;ol class = 'mono-space'&amp;amp;gt;\n\t&amp;amp;lt;li&amp;amp;gt;&amp;amp;lt;a href=&quot;&amp;amp;lt;?php echo $_SERVER&#x5B;'PHP_SELF'] . '?debug-action=current_dir';?&amp;amp;gt;&quot;&amp;amp;gt;Run&amp;amp;lt;\/a&amp;amp;gt; - List Current Directory - debug_dir_list()&amp;amp;lt;\/li&amp;amp;gt;\n\t&amp;amp;lt;li&amp;amp;gt;&amp;amp;lt;a href=&quot;&amp;amp;lt;?php echo $_SERVER&#x5B;'PHP_SELF'] . '?debug-action=current_dir_1';?&amp;amp;gt;&quot;&amp;amp;gt;Run&amp;amp;lt;\/a&amp;amp;gt; - List Current Directory + Children(1) - debug_dir_list(1)&amp;amp;lt;\/li&amp;amp;gt;\n\t&amp;amp;lt;li&amp;amp;gt;&amp;amp;lt;a href=&quot;&amp;amp;lt;?php echo $_SERVER&#x5B;'PHP_SELF'] . '?debug-action=parent_dir';?&amp;amp;gt;&quot;&amp;amp;gt;Run&amp;amp;lt;\/a&amp;amp;gt; - List Parent Directory  + Children(0) - debug_dir_list(0, &quot;..\/&quot;)&amp;amp;lt;\/li&amp;amp;gt;\n\t&amp;amp;lt;li&amp;amp;gt;&amp;amp;lt;a href=&quot;&amp;amp;lt;?php echo $_SERVER&#x5B;'PHP_SELF'] . '?debug-action=parent_dir_1';?&amp;amp;gt;&quot;&amp;amp;gt;Run&amp;amp;lt;\/a&amp;amp;gt; - List Parent Directory + Children(1) - debug_dir_list(1, &quot;..\/&quot;)&amp;amp;lt;\/li&amp;amp;gt;\n\t&amp;amp;lt;li&amp;amp;gt;&amp;amp;lt;a href=&quot;&amp;amp;lt;?php echo $_SERVER&#x5B;'PHP_SELF'] . '?debug-action=parent_dir_2';?&amp;amp;gt;&quot;&amp;amp;gt;Run&amp;amp;lt;\/a&amp;amp;gt; - List Parent Directory + Children(2) - debug_dir_list(2, &quot;..\/&quot;)&amp;amp;lt;\/li&amp;amp;gt;\n&amp;amp;lt;\/ol&amp;amp;gt;\n&amp;amp;lt;hr&amp;amp;gt;\n&amp;amp;lt;pre&amp;amp;gt;\n&amp;amp;lt;?php\nif ( !isset($_GET&#x5B;&quot;debug-action&quot;]) ){\n\t$get_action = &quot;&quot;;\n}else{\n\t$get_action = $_GET&#x5B;&quot;debug-action&quot;];\n}\necho basename(__FILE__) . &quot;\\n&quot;;\necho &quot;PHP version: &quot; . phpversion() . &quot;\\n&quot;;\necho &quot;debug-action=&quot; . $get_action . &quot;\\n&quot;;\nswitch($get_action){\n\tcase 'current_dir':\n\t\techo &quot;File list: &quot; . print_r(debug_dir_list(), true);\n\tbreak;\n\tcase 'current_dir_1':\n\t\techo &quot;File list: &quot; . print_r(debug_dir_list(1), true);\n\tbreak;\n\tcase 'parent_dir':\n\t\techo &quot;File list : &quot; . print_r(debug_dir_list(0, &quot;..\/&quot;), true);\n\tbreak;\n\tcase 'parent_dir_1':\n\t\techo &quot;File list: &quot; . print_r(debug_dir_list(1, &quot;..\/&quot;), true);\n\tbreak;\n\tcase 'parent_dir_2':\n\t\techo &quot;File list: &quot; . print_r(debug_dir_list(2, &quot;..\/&quot;), true);\n\tbreak;\n}\n?&amp;amp;gt;\n&amp;amp;lt;\/pre&amp;amp;gt;\n&amp;amp;lt;\/body&amp;amp;gt;\n&amp;amp;lt;\/html&amp;amp;gt;\n<\/pre>\n<p>[ad name=&#8221;Google Adsense&#8221;]<\/p>\n<div id=\"fb-root\"><\/div>\n<p><script src=\"https:\/\/connect.facebook.net\/en_US\/all.js#appId=105467682877384&amp;xfbml=1\"><\/script><\/p>\n<div id=\"fb-root\"><\/div>\n<p><script src=\"https:\/\/connect.facebook.net\/en_US\/all.js#xfbml=1\"><\/script><\/p>\n<p><!-- Place this render call where appropriate --><br \/>\n<script type=\"text\/javascript\"><br \/>\n  (function() {<br \/>\n    var po = document.createElement('script'); po.type = 'text\/javascript'; po.async = true;<br \/>\n    po.src = 'https:\/\/apis.google.com\/js\/plusone.js';<br \/>\n    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);<br \/>\n  })();<br \/>\n<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>By Lon Hosford You can avoid writing recursive function to traverse through tree structures like you server file system. PHP has several Iterator classes starting with version 5. In this article we will look at the RecursiveDirectoryIterator class. We will build a utility function to use the RecursiveDirectoryIterator class to provide a text listing of [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3182,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[57],"class_list":["post-3181","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-general","tag-php-2"],"_links":{"self":[{"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/posts\/3181","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/comments?post=3181"}],"version-history":[{"count":27,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/posts\/3181\/revisions"}],"predecessor-version":[{"id":3781,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/posts\/3181\/revisions\/3781"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/media\/3182"}],"wp:attachment":[{"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/media?parent=3181"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/categories?post=3181"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/tags?post=3181"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}