Listing the Contents of a Directory With PHP

Following is a quick tutorial explaining how to list the contents of a directory with PHP. Much of this information is taken from the official PHP documentation of the opendir() function.

To begin with, you need to determine which directory you want to list. Start by storing the location of that directory in a variable. If you want to list the contents of the directory in which your script is running, you can use the realpath function to find the full path to that directory. That would look something like:
$dir = realpath('./');
The function above will find the full, absolute path to the current directory and store it as the “$dir” variable.

Next, write yourself a function that looks similar to:
define('HOMEPATH','/home/user/directory'); // Change this to match the absolute path to the root of your Web site (no trailing slash)
define('HOMEURL',''); // Change this to match the URL to the root of your Web site (no trailing slash)

function listdir($dir) {
$list = array();
// Open a known directory, and proceed to read its contents
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) {
if($file !== '.' && $file !== '..' && $file !== 'index.php') {
if(is_dir($dir.'/'.$file)) {
$tmparr = listdir($dir.'/'.$file);
if(count($tmparr)) {
$list[] = '<li><strong>'.$file.'</strong><ul>'.implode('',$tmparr).'</ul></li>'."\n";
else {
$list[] = '<li><a href="'.str_replace(array(HOMEPATH,'&',' '),array(HOMEURL,'&amp;','%20'),$dir.'/'.$file).'">'.str_replace(array('&'),array('&amp;'),$file).'</a></li>'."\n";
return $list;

The function above will recursively search the directory and create an unordered list of links to each of the files found inside. It will ignore “index.php” in each of those directories.

To run the function and print the list onto your screen, you would use code similar to:
$list = listdir($dir);
if(count($list)) { // Check to make sure the list returned had at least one item
echo '<ul>'.implode('',$list).'</ul>';

That’s about all there is to it. I hope that helps someone.

Edit: On July 14, 2009, I updated the code in this post due to a potential bug. The code used in this post has been tested and is available in a ZIP file in this post.