Функция получает на вход три параметра - имя директории, margin - начальная глубина (целое число, по умолчанию - 0) и print - печатать (булево, по умолчанию true).
Функция возвращает массив файлов, устроенный следующим образом: в каждой строке массива есть три элемента. Первый - имя файла или директории; второй - глубина файла, третий - true, если файл является папкой, и false в противном случае.
Если параметр print равен true, то в конце функции происходит печать списка файлов с соблюдением глубины: на каждую единицу глубины приходится по 4 пробела. Выводимый текст заключён в тэг <pre>, символ разрыва строки - \n.
Функция работает рекурсивно. Она прочитывает текущую директорию, отбрасывая . и .., и если находит директорию, то запускает себя с параметром глубины на 1 больше, а потом собирает эти данные в свой массив.

Исходный код:
<?php
function fileList($dir,$margin=0,$print=true){
	//Увеличиваем глубину
	$margin++;
	$files=array();
	//Открываем и читаем директорию
	$dh  = opendir($dir);
	while (false !== ($filename = readdir($dh))) {
		//Ненужные . и .. пропускаем
		if($filename<>"." && $filename<>".."){
			//Если найдена папка, то просматриваем её и добавляем результаты в наш массив после собственно папки
			if(is_dir($dir."/".$filename)){
				$files[] = array($filename,$margin,true); //true указывает на то, что это папка
				$arr=filelist($dir."/".$filename,$margin,false);
				if(!empty($arr)){
					foreach($arr as $fn){
						$files[]=$fn;
					}
				}
			//Иначе просто добавляем папку в массив
			}else{
				$files[] = array($filename,$margin,false); //false указывает на то, что это не папка.
			}
		}
	}
	
	//Модуль печати. Включается, только если параметр print был равен true
	if($print){
		print("<pre>");
		if(!empty($files)){
			//Печатаем файлы с отступами
			foreach($files as $file){
				for($i=0;$i<$file[1];$i++){
					print("    ");
				}
				print($file[0]);
				if($file[2]){print("/");}
				print("\n");
			}
		}else{
			print("Нет файлов.");
		}
		print("</pre>");
	}
	
	//Возвращаем массив файлов, устроенный следующим образом: в каждой строке массива есть три элемента.
	//Первый - имя файла или директории; второй - глубина файла,
	//третий - true, если файл является папкой, и false в противном случае.
	return($files);
}
?>