Helpful Information
 
 
Category: Post a PHP snippet
Recursive Directory Listing (Show full directory structure)

This function will read the full structure of a directory. It's recursive becuase it doesn't stop with the one directory, it just keeps going through all of the directories in the folder you specify.


<?php

function getDirectory( $path = '.', $level = 0 ){

$ignore = array( 'cgi-bin', '.', '..' );
// Directories to ignore when listing output. Many hosts
// will deny PHP access to the cgi-bin.

$dh = @opendir( $path );
// Open the directory to the handle $dh

while( false !== ( $file = readdir( $dh ) ) ){
// Loop through the directory

if( !in_array( $file, $ignore ) ){
// Check that this file is not to be ignored

$spaces = str_repeat( '&nbsp;', ( $level * 4 ) );
// Just to add spacing to the list, to better
// show the directory tree.

if( is_dir( "$path/$file" ) ){
// Its a directory, so we need to keep reading down...

echo "<strong>$spaces $file</strong><br />";
getDirectory( "$path/$file", ($level+1) );
// Re-call this same function but on a new directory.
// this is what makes function recursive.

} else {

echo "$spaces $file<br />";
// Just print out the filename

}

}

}

closedir( $dh );
// Close the directory handle

}

?>

Example Calls:



getDirectory( "." );
// Get the current directory

getDirectory( "./files/includes" );
// Get contents of the "files/includes" folder


Functions Used:
http://www.php.net/opendir
http://www.php.net/readdir
http://www.php.net/closedir
http://www.php.net/in-array
http://www.php.net/str-repeat
http://www.php.net/is-dir

Thanks man. I didn't want to spend the time writing and thinking about doing this. Helped alot with this little snippet ^^ Thanks again :)

I also wanted to say thanks a lot. This is exactly what I was looking for. :thumbsup:

sorry but this doesn't work on my php server.. I NEED HELP lol.. if i want to show a directory /public_html/flash/ what do i have to put? and what is the "level" variable about??
thanx.

Jamez.

ok peeps, soz to double post, just solved it - you need the full directory path including this /home/user/public/foldername/

thanx.

Jamez.

This function does the same thing but is a _LOT_ faster:


function get_dir_iterative($dir = '.', $exclude = array( 'cgi-bin', '.', '..' ))
{
$exclude = array_flip($exclude);
if(!is_dir($dir))
{
return;
}

$dh = opendir($dir);

if(!$dh)
{
return;
}

$stack = array($dh);
$level = 0;

while(count($stack))
{
if(false !== ( $file = readdir( $stack[0] ) ) )
{
if(!isset($exclude[$file]))
{
print str_repeat('&nbsp;', $level * 4);
if(is_dir($dir . '/' . $file))
{
$dh = opendir($file . '/' . $dir);
if($dh)
{
print "<strong>$file</strong><br />\n";
array_unshift($stack, $dh);
++$level;
}
}
else
{

print "$file<br />\n";
}
}
}
else
{
closedir(array_shift($stack));
--$level;
}
}
}

Both code don't work for me, I only see a blank page.

Can someone help ?

Peuplarchie, did you actually call the function or did you just copy/paste the code from above into your php page? Because you have to include the above code in <?PHP and ?> and then actually call it inside the php tags like so:

<?
//Function code
//....

//Now call it by using one of these,
//depending on which function you chose above:
getdirectory('.');
//or
get_dir_iterative(/*etc.*/);
?>

marek_mar, Dude, that code is lightening fast but I'm finding it only goes two levels deep.

Not being sniffy, should probably rewrite/repost myself: but the function is both getting the directory listing and printing the result, would be nice if it returned the data from the recursive directory scan (probably in an array) so programmer can specify how it is shown, either print or send to HTML template etc. keep functions doing one thing, getting data from filesystem or printing the result makes it more re-usable.

<?
function getDirectory($path = '.', $ignore = '') {
$dirTree = array ();
$dirTreeTemp = array ();
$ignore[] = '.';
$ignore[] = '..';

$dh = @opendir($path);

while (false !== ($file = readdir($dh))) {

if (!in_array($file, $ignore)) {
if (!is_dir("$path/$file")) {

$dirTree["$path"][] = $file;

} else {

$dirTreeTemp = getDirectory("$path/$file", $ignore);
if (is_array($dirTreeTemp))$dirTree = array_merge($dirTree, $dirTreeTemp);
}
}
}
closedir($dh);

return $dirTree;
}

$ignore = array('.htaccess', 'error_log', 'cgi-bin', 'php.ini', '.ftpquota');

$dirTree = getDirectory('/your/path/here', $ignore);
?>
<pre>
<?
print_r($dirTree);
?>
</pre>


Not Sure if it's the best, and likely is not, but I modified the first function to get things working for now. This returns an array so that when i go back through the array, I can concatenate my keys with my values for use with something like fopen...

The getDirectory function is totally awesome! and exactly what i needed. here's the thing tho: when i was hacking it up on my dev box it was working great. but then, once i got it the way i wanted it, i uploaded the files to the web server, and now everything is coming up in random order.

is there a way to force it to read alphabetically? Is is my web server? is it something else entirely? :confused: anybody know of this issue?

TIA
~joel

The getDirectory function is totally awesome! and exactly what i needed. here's the thing tho: when i was hacking it up on my dev box it was working great. but then, once i got it the way i wanted it, i uploaded the files to the web server, and now everything is coming up in random order.

is there a way to force it to read alphabetically? Is is my web server? is it something else entirely? :confused: anybody know of this issue?

TIA
~joel

Here's my code:

function getDirectory( $path = '.', $level = 0 ){

$ignore = array( 'cgi-bin', '.', '..' );

$dh = @opendir( $path );

while( false !== ( $file = readdir( $dh ) ) ){

if( !in_array( $file, $ignore ) ){

if( is_dir( "$path/$file" ) ){
$dir = $path . $file;

echo "<div class=\"highslide-gallery\">\n
<center>
<a id=\"gallery-opener\" href=\"javascript:;\" onclick=\"document.getElementById('thumb$level').onclick()\">$file</a>\n
</center>
<div class=\"hidden-container\">\n";

$dh1 = @opendir( $dir );

while( false !== ( $image = readdir( $dh1 ) ) ){
if( !in_array( $image, $ignore ) ){
if( !is_dir( "$dir/$image" ) ){
echo "<a id=\"thumb$level\" class='highslide' href='$dir/$image' title=\"\" onclick=\"return hs.expand(this, config$level)\">$image</a>\n";
}
}
}
echo "</div>\n</div>\n\n";
$level++;
}
}
}
closedir( $dh );
}

getDirectory('images/');

<?php

/*
** Put the following line into an index.php,
** with first line: include_once("dirLister.class.php");
** Then erase the following line.
*/
$dirLister = new dirLister();

/*
** After running this once you will find two new files in the current directory:
** config.ini
** links.ini
** Once they exist, you might want to edit them, as needed, to get what you want.
*/

class dirLister
{
var $searchRootUrlPath;
var $searchRootFilePath;
var $currentDirUrlPath;
var $currentDirFilePath;
var $currentDisplayName=null;
var $defaultDisplayName;
var $linkTypes=array();
var $links=array();
var $allowedLinkTypesfile;
var $config=array();
var $dbg=false;

function __construct()
{
$this->init();
$this->readLinkTypes();
$this->getLinks();
$this->getDefaultDisplay();
$this->show();
}

function init()
{
if(@stat("config.ini"))
{
/* A config.ini file does exist. You can edit this file, as needed, to search any permissable directory. */
$lines = file("config.ini");
foreach ($lines as $aline)
{
$tokens = explode("=",$aline);
$label = trim($tokens[0]);
$value = trim($tokens[1]);
if(stristr($label, "path")){
if(strlen(strrchr($value,'/')) != 1){
$value .= '/';
}
}
$this->config[$label] = $value;
}
$this->searchRootUrlPath = $this->config['searchRootUrlPath'];
$this->searchRootFilePath = $this->config['searchRootFilePath'];
}
else
{
if(strstr($_SERVER['SCRIPT_FILENAME'],"home"))
{
/* no config.ini file exists. If "home" appears in the path
** we'll make a desperate attempt to make this work. We'll assume
** the current path looks something like this (which it may not):
** /home/sandy/public_html/images/
*/
$dirs = explode('/',dirname($_SERVER['SCRIPT_FILENAME']));
$tmpUrlPath='/~' . $dirs[2] ;
$zapper = '/' . $dirs[1] . '/'. $dirs[2] . '/' . $dirs[3] . '/';

$tmp = ereg_replace($zapper,"", dirname($_SERVER['SCRIPT_FILENAME']));
$tmpUrlPath .= '/'.$tmp . '/';
$this->config['searchRootFilePath'] = dirname($_SERVER['SCRIPT_FILENAME']);
$this->config['searchRootUrlPath'] = $tmpUrlPath;
$this->searchRootFilePath = $this->config['searchRootFilePath'];
$this->searchRootUrlPath = $this->config['searchRootUrlPath'];
}
else
{
/*
** No config.ini file exists. "home" does not appear in the path.
** So we'll assume we're in the global document root instead of a ~user/public_html directory
** This should work, regardless $_SERVER['DOCUMENT_ROOT']
*/
$this->searchRootFilePath = dirname($_SERVER['SCRIPT_FILENAME']).'/';
$this->searchRootUrlPath = '/' . ereg_replace($_SERVER['DOCUMENT_ROOT'],"", $this->searchRootFilePath);
}
}

if(isset($_GET['dbg']))
$this->dbg=true;

if($this->dbg){
echo "Url: ", $this->searchRootUrlPath ,"<br>";
echo "File: ", $this->searchRootFilePath , "<br>";
}
$this->setCurrentDir();
}

function setCurrentDir()
{
$this->currentDirUrlPath = $this->searchRootUrlPath;
$this->currentDirFilePath = $this->searchRootFilePath;
if(isset($_GET['page']))
{
$parm = preg_replace("/^\.+/","", $_GET['page']);
$parm = preg_replace("/^\/+/","", $parm);
if(is_dir($this->currentDirFilePath . $parm)){
$this->currentDirUrlPath = $this->currentDirUrlPath . $parm . '/';
$this->currentDirFilePath = $this->currentDirFilePath . $parm . '/';
}else{
$this->currentDirUrlPath = $this->currentDirUrlPath . dirname($parm) . '/';
$this->currentDirFilePath = $this->currentDirFilePath . dirname($parm) . '/';
}
}
if($this->dbg){
echo "currentDirUrlPath: ", $this->currentDirUrlPath, "<br>";
echo "currentDirFilePath: ", $this->currentDirFilePath, "<br>";
}
}

function defaultCSS()
{

$css = <<< ENDO
body
{
background: #eeeeff;
}

.shortlink
{
background: #aaaaff;
padding: 0.5em;
margin: 0.5em;
width: 10em;
border: 3px outset #cccccc;
}

#wrapperDiv
{
margin-left: auto;
margin-right: auto;
padding: 1em;
width: 90%;
height: 75%;
position: relative;
background: #ffaaaa;
height: 95%;
border: 2px outset #888888;
}

#navigationDiv
{
position: relative;
float: left;
margin: 0 auto;
padding: 0.5em;
background: #ffaaaa;
width: 35%;
}

#displayDiv
{
float: left;
margin: 0 auto;
padding: 0.5em;
background: #ffaaaa;
width: 50%;
min-height: 98%;
}

p.linkp
{
background: #aaaaff;
padding: 0.5em;
margin: 0.5em;
width: 90%;
border: 3px outset #cccccc;
}

a:{ text-decoration: none; }
a:hover{ text-decoration: underline; font-style: italic; font-weight: bold; }
p.linkp:hover{ border: 3px inset #cccccc; }

a.buttonlike
{
text-decoration: none;
display: inline;
background: #aaaaff;
padding: 0.5em;
margin: 0.5em;
width: 5em;
border: 3px outset #cccccc;
}
a.buttonlike:hover { text-decoration: underline; font-style: italic; font-weight: bold; }
ENDO;

$fp = fopen("utils.css", "w");
if($fp == null)
$this->fatalError("could not open missing utils.css for writing");
fwrite($fp, $css);
fclose($fp);
}

function fatalError($msg)
{
echo "<b>ERROR: </b>", $msg, "<br>";
exit();
}

function getDefaultDisplay()
{
if(isset($_GET['page']))
{
if(!is_dir($this->currentDirFilePath.$_GET['page']))
$this->currentDisplayName = basename($_GET['page']);
}
else
$this->currentDisplayName=$this->defaultDisplayName;

if($this->dbg){
echo "currentDisplayName: ", $this->currentDisplayName, "<br>";
}
return $ret;
}

function linkTypeDefaults()
{
$linktypes = <<< ENDO
html=link
htm=fragment
php=link
txt=text
jpeg=image
gif=image
jpg=image
JPG=image
JPEG=image
pdf=link
xls=link
doc=link
gz=link
tar=link
zip=link
pdf=link
mpe=link
mpeg=link
mpg=link
mov=link
mp3=link
wav=link
ENDO;

$fp = fopen("links.ini", "w");
if($fp == null)
$this->fatalError("could not open missing utils.css for writing");
fwrite($fp, $linktypes);
fclose($fp);
}

function readLinkTypes()
{
if([email protected]("links.ini")){
$this->linkTypeDefaults();
}
$this->allowedLinkTypesfile="links.ini";
$inilines=file($this->allowedLinkTypesfile);
foreach ($inilines as $aline)
{
$tokens = explode('=',$aline);
$this->linkTypes[trim($tokens[0])] = trim($tokens[1]);
}
}

function show()
{
echo $this->startHTML();
echo $this->mkNavigationDiv();
echo $this->mkDisplayDiv();
echo $this->endHTML();
}

function validLink($path)
{
$ret = false;
$suffix = $this->getSuffix($path);
if(isset($this->linkTypes[$suffix])){
$ret = true;
}
return $ret;
}

function mkLink($page)
{
$linktype = trim($this->links[$page]);

if($this->links[$page] == "dir")
$relativePath = ereg_replace($this->searchRootUrlPath,"",$this->currentDirUrlPath).$page;
else
$relativePath = ereg_replace($this->searchRootUrlPath,"",$this->currentDirUrlPath);

$relativePath = preg_replace("/^\.\//","",$relativePath);

$ret = '<p class="linkp">';
if ($linktype == "link"){
$ret .= '<a href="'
.ereg_replace(dirname($this->searchRootUrlPath)
.'/',"",$this->currentDirUrlPath).$page.'">'.$page.'</a>';
}
else if($linktype == "image"){
$ret .= '<a href="'. $_SERVER['PHP_SELF'].'?page='.$relativePath.$page.'">'.$page.'</a>';
}

else if($linktype == "text"){
$ret .= '<a href="'. $_SERVER['PHP_SELF'].'?page='.$relativePath.$page.'">'.$page.'</a>';
}
else if($linktype == "fragment"){
$ret .= '<a href="'. $_SERVER['PHP_SELF'].'?page='.$relativePath.$page.'">'.$page.'</a>';
}
else if($linktype == "dir"){
$ret .= '<a href="'. $_SERVER['PHP_SELF'].'?page='.$relativePath.'"> ./'.$page.'</a>';
}
$ret .= '</p>'."\n";

return $ret;
}

function getLinks()
{
if ($dir_handle = @opendir($this->currentDirFilePath))
{
while (($ffile = readdir($dir_handle)) !== false)
{
$file = trim($ffile);
if($file[0] !== '.')
{
if($this->validLink($file)){
$linkType = $this->linkTypes[$this->getSuffix($file)];
if($this->defaultDisplayName==null && (
$linkType == 'image'
|| $linkType == 'fragment'
|| $linkType == 'text'
)){
$this->defaultDisplayName = $file;
}
$this->links[trim($file)] = trim($linkType);
}else if(is_dir($this->currentDirFilePath . $file))
{
$this->links[trim($file)] = "dir";
}
}
}
closedir($dir_handle);
}
}

function mkNavigationDiv()
{
$ret = ' <div id="navigationDiv">'."\n";
foreach (array_keys($this->links) as $akey)
{
$ret .= $this->mkLink($akey);
}

$test1 = basename(dirname($this->currentDirUrlPath));
$test2 = basename(dirname($this->searchRootUrlPath));

$upHref='';
if($test1 != $test2)
{
$tmp = dirname($this->currentDirUrlPath) . '/';

if($test1 == basename($this->searchRootUrlPath)) {
$upHref = $_SERVER['PHP_SELF'];
}
else {
$upHref = $_SERVER['PHP_SELF'].'?page='.$test1;
}
$ret .= '<br><a href="'.$upHref.'"> <b>Move Up</b> </a><br>';
}
$ret .= ' </div>';

return ($ret);
}

function mkImageArea()
{
$ret = '';
if($this->links[$this->currentDisplayName] == null)
$ret = '<img src="'.$this->currentDirUrlPath . $this->defaultDisplayName.'" alt="'.$this->defaultDisplayName.'">';
else
$ret = '<img src="'.$this->currentDirUrlPath . $this->currentDisplayName.'" alt="'.$this->currentDisplayName.'">';
return $ret;
}

function mkLinkArea()
{
return "<b>" . $this->searchRootUrlPath . $this->currentDisplayName . "</b><br>";
}

function mkTextArea()
{
$ret='';
$lines = file ($this->searchRootFilePath .$this->currentDisplayName);
foreach ($lines as $aline)
{
$ret .= $aline . "<br>";
}
return $ret;
}

function mkHTMLFragmentArea()
{
return file_get_contents($this->searchRootFilePath .$this->currentDisplayName);
}

function getDisplay()
{
$ret='';
$linktype = $this->links[trim(basename($this->currentDisplayName))];
if($linktype == null){
if(is_dir($this->currentDirFilePath)){
$linktype = $this->links[trim(basename($this->defaultDisplayName))];
}
}
switch($linktype)
{
case "dir":
$ret = $this->mkImageArea();
break;
case "image":
$ret = $this->mkImageArea();
break;
case "text":
$ret = $this->mkTextArea();
break;
case "fragment":
$ret = $this->mkHTMLFragmentArea();
break;
}
return $ret;
}

function mkDisplayDiv()
{
$ret = ' <div id="displayDiv">';
$ret .= $this->getDisplay();
$ret .= ' </div>'."\n";
return $ret;
}

function startHTML()
{
if([email protected]("utils.css"))
$this->defaultCSS();

$ret = '
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>gallery version chooser</title>
<link rel="stylesheet" href="utils.css" type="text/css">
</head>
<body>'."\n";

$ret .= '<div id="wrapperDiv">'."\n";
return $ret;
}

function endHTML()
{
return "\n" . '</div></body></html>'. "\n";
}

function getSuffix($file, $withdot=null)
{
$suffix = substr(strrchr(basename($file),'.'),1);
if(isset($withdot))
$suffix = '.' . $suffix;
return $suffix;
}

function stripSuffix($file)
{
$suffix = getSuffix($file, "withdot");
return preg_replace("/$suffix/", "", $file);
}
}

?>

Hi,

This script works pretty well except that the files list is not ordered. I'd like to sort it alphabetically. Any idea how to do that?

For example, I got this:

0012.jpg
0011.pdf
0024.pdf
0004.jpg
0018.pdf
0008.pdf

While I'd like to get this:

0004.jpg
0008.pdf
0011.pdf
0012.jpg
0018.pdf
0024.pdf

Thanks for any help.

Hi,

This script works pretty well except that the files list is not ordered. I'd like to sort it alphabetically. Any idea how to do that?

For example, I got this:

0012.jpg
0011.pdf
0024.pdf
0004.jpg
0018.pdf
0008.pdf

While I'd like to get this:

0004.jpg
0008.pdf
0011.pdf
0012.jpg
0018.pdf
0024.pdf

Thanks for any help.

Before sorting the listed files/directories alphabetically, I coverted the function into the way listing the files/directories in list(ul/li) manner instead of the current 'intent' one. I reckon the list way is the most proper way to list nested items. Here is the new function:


function getDirectory( $path = '.'){

$ignore = array( 'cgi-bin', '.', '..' );
// Directories to ignore when listing output. Many hosts
// will deny PHP access to the cgi-bin.

$dh = @opendir( $path );
// Open the directory to the handle $dh

while( false !== ( $file = readdir( $dh ) ) ){
// Loop through the directory

if( !in_array( $file, $ignore ) ){
// Check that this file is not to be ignored

// Just to add spacing to the list, to better
// show the directory tree.

if( is_dir( "$path/$file" ) ){
// Its a directory, so we need to keep reading down...


//Add a class as selector for the jQuery sorting later.
echo "<li>$file<ul class='has-children'>";
getDirectory( "$path/$file");
// Re-call this same function but on a new directory.
// this is what makes function recursive.
echo "</li>";

} else {

echo "<li>$file</li>";
// Just print out the filename

}



}



}
echo "</ul>";
closedir( $dh );
// Close the directory handle

}
//Add a class as selector for the jQuery sorting later.
echo "<ul class='has-children'>";
getDirectory( "." );

Then add the following jQuery codes to sort the lists:



<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
$(function() {
$('ul.has-children').each(function() {
var $t=$(this);
var Li=$t.find('>li').get();
Li.sort(function(a, b) {
var A = $(a).text().toUpperCase();
var B = $(b).text().toUpperCase();
if (A < B) return -1; // changing to 1 to sort in DESC order...
if (A > B) return 1; // changing to -1 to sort in DESC order...
return 0;
});
$.each(Li,function(i,v) {
$t.append(v);
});
});
</script>


Have fun :)

Hi! I was looking for a code snippet for directory traversal and i found tours (i feel too lazy tonight to do it by myself) :)
I tested on linux and works ok, on windows ok except for long paths.

And I actually need to index some dirs and files that have a really deep dir structure.
It just freezes when the path is longer than 255...
Do you have any ideas on how i can traverse such a structure?
Thank you very much!
Any help is really appreciated!

I like (turtles) natcasesort($files);

To be honest, I don't really like the supressing of potentional errors( @opendir ).
I was actually creating an online file management system, and already had this coded. (Currently secured it by IP Access).



<?php

if($_SERVER['REMOTE_ADDR'] != 'YOUR_IP') {

die("Only the webmaster can access this page's content. Please go back and open another file.");

} else {

if(isset($_GET['dir'])) {

if($_GET['dir'] == "www") {

$dir = './';

} else {

$dir = $_GET['dir'];

}

} else {

$dir = '.';

}

if($dir != '.') {
$dirlist = explode('/', $dir);
$back = substr_replace($dir, '', strpos($dir, '/'.end($dirlist)), strlen('/'.end($dirlist)));

echo '<a href="./management.php?dir='.$back.'">< Go back</a><br /><br />';
}

$dirlist = array();
$filelist = array();
$i = 0;

foreach(new DirectoryIterator($dir) as $file) {

if((!$file->isDot()) && ($file->getFilename() != basename($_SERVER['PHP_SELF']))) {

if($file->isDir()) {

$dirlist[$i]['dir'] = $dir;
$dirlist[$i]['name'] = $file->GetFilename();
$dirlist[$i]['type'] = $file->GetType();

} else {

$filelist[$i]['dir'] = $dir;
$filelist[$i]['name'] = $file->GetFilename();
$filelist[$i]['type'] = $file->GetType();
$filelist[$i]['size'] = $file->getSize();
$filelist[$i]['lmod'] = $file->getMTime();

}

$i++;

}

}

echo '<table border="1px">';
echo '<tr>';
echo '<th>File Name</th>';
echo '<th>File Type</th>';
echo '<th>File Size</th>';
echo '<th>Last Modified</th>';
echo '<th>Edit</th>';
echo '<th>Delete</th>';
echo '</tr>';


foreach($dirlist as $dirs) {
echo '<tr>';
echo '<td><a href="./management.php?dir='.$dirs['dir'].'/'.$dirs['name'].'">'.$dirs['name'].'</a></td>';
echo '<td>'.strtoupper($dirs['type']).'</td>';
echo '<td>N/A</td>';
echo '<td>N/A</td>';
echo '<td><a href="./edit.php?file='.$dirs['dir'].'/'.$dirs['name'].'&is_dir=1">Edit</a></td>';
echo '<td><a href="./delete.php?file='.$dirs['dir'].'/'.$dirs['name'].'&is_dir=1">Delete</a></td>';
echo '</tr>';
}

foreach($filelist as $files) {
echo '<tr>';
echo '<td><a href="./management.php?dir='.$files['dir'].'/'.$files['name'].'">'.$files['name'].'</a></td>';
echo '<td>'.strtoupper($files['type']).'</td>';

if($files['size'] >= 1024 && $files['size'] < 1048576) {

$files['size'] = round(($files['size'] / 1024), 2);
echo '<td>'.$files['size'].' kB</td>';

} else if($files['size'] >= 1048576 && $files['size'] < 1073741824){

$files['size'] = round(($files['size'] / 1048576), 2);
echo '<td>'.$files['size'].' mB</td>';

} else if($files['size'] >= 1073741824) {

$files['size'] = round(($files['size'] / 1073741824), 2);
echo '<td>'.$files['size'].' gB</td>';

} else {

echo '<td>'.$files['size'].' B</td>';

}

echo '<td>'.date("d/m/y H:i:s", $files['lmod']).'</td>';

echo '<td><a href="./edit.php?file='.$files['dir'].'/'.$files['name'].'&is_dir=0">Edit</a></td>';
echo '<td><a href="./delete.php?file='.$files['dir'].'/'.$files['name'].'&is_dir=0">Delete</a></td>';
echo '</tr>';
}


echo '</table>';
echo '<br /><br />';
echo '<a href="./create.php?is_dir=1&dir='.$dir.'">Create a Directory</a> - <a href="./create.php?is_dir=0&dir='.$dir.'">Create a File</a>';

}

?>


(Not going to give the other pages tho, I might release the full source when I've got it done).
{

How it eventually looks:
http://img716.imageshack.us/img716/521/managementr.png

}
(only thing that needs to be added that it takes you to the actual page, instead of trying to open it as a dir when you click a file)

# system call do recursive dir listing. assign listing to array and sort on each
# pass with foreach loop.
# once you have array you can go further as sorting & recursion done.

$rtv = `ls -RAFr /home/web.symfony/`; // system call to start listing
$dir = array();

foreach( preg_split("/\n/", $rtv) as $line ) {
if(preg_match("/:$/", $line)) { // if directory
if($line && $current_path) { // after first pass
asort($dir[$current_path]); // cool & easy sort
}
$current_path = preg_replace("/:$/", '', $line); // discard : from the path
}else if ($line != '') {
$dir[$current_path][] = $line; // listing of the previous pass
}
}

print_r($dir);

Before sorting the listed files/directories alphabetically, I coverted the function into the way listing the files/directories in list(ul/li) manner instead of the current 'intent' one. I reckon the list way is the most proper way to list nested items. Here is the new function:


function getDirectory( $path = '.'){

$ignore = array( 'cgi-bin', '.', '..' );
// Directories to ignore when listing output. Many hosts
// will deny PHP access to the cgi-bin.

$dh = @opendir( $path );
// Open the directory to the handle $dh

while( false !== ( $file = readdir( $dh ) ) ){
// Loop through the directory

if( !in_array( $file, $ignore ) ){
// Check that this file is not to be ignored

// Just to add spacing to the list, to better
// show the directory tree.

if( is_dir( "$path/$file" ) ){
// Its a directory, so we need to keep reading down...


//Add a class as selector for the jQuery sorting later.
echo "<li>$file<ul class='has-children'>";
getDirectory( "$path/$file");
// Re-call this same function but on a new directory.
// this is what makes function recursive.
echo "</li>";

} else {

echo "<li>$file</li>";
// Just print out the filename

}



}



}
echo "</ul>";
closedir( $dh );
// Close the directory handle

}
//Add a class as selector for the jQuery sorting later.
echo "<ul class='has-children'>";
getDirectory( "." );

Then add the following jQuery codes to sort the lists:



<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
$(function() {
$('ul.has-children').each(function() {
var $t=$(this);
var Li=$t.find('>li').get();
Li.sort(function(a, b) {
var A = $(a).text().toUpperCase();
var B = $(b).text().toUpperCase();
if (A < B) return -1; // changing to 1 to sort in DESC order...
if (A > B) return 1; // changing to -1 to sort in DESC order...
return 0;
});
$.each(Li,function(i,v) {
$t.append(v);
});
});
</script>


Have fun :)
Here is the PHP way to do the same sorting as the above with jQuery:


<?
$tree=array();

function getDirectory( $path = '.'){

$ignore = array( 'cgi-bin', '.', '..' );
// Directories to ignore when listing output. Many hosts
// will deny PHP access to the cgi-bin.

$dh = @opendir( $path );
// Open the directory to the handle $dh

//Make counter
$j=0;
$temp=array();

while( false !== ( $file = readdir( $dh ) ) ){
// Loop through the directory

if( !in_array( $file, $ignore ) ){
// Check that this file is not to be ignored

// Feed with file name
$temp[$j]['name']=$file;

if( is_dir( "$path/$file" ) ){
// Its a directory, so we need to keep reading down...
$temp[$j]['children']=getDirectory( "$path/$file");
}

}

$j++; //counting

}
return $temp;

closedir( $dh );
// Close the directory handle

}//end of function

//Put the file directory system in an array first...
$tree=getDirectory("/your-dirtory/here");

$type='desc'; //set sorting type 'desc' or 'asc'


//recursive function for sorting arrays
function getSort(&$temp) {
global $type;

switch ($type) {
case 'desc':
rsort($temp);
break;
case 'asc':
sort($temp);
break;
}

foreach($temp as &$t) {
if(is_array($t['children']))
getSort($t['children']);
}
} //end of function

//Go through arrays again for sorting...now we have new sorted array $tree...
getSort($tree);
?>
<pre>
<?
print_r($tree); // output
?>
</pre>

Have funs:thumbsup:

hello,
well for me this function make the error :
Warning: readdir() expects parameter 1 to be resource, boolean given
for
while (false !== ($file = readdir($dh))) {

any idea? :)

I must say I don't think it's a good practice to put html in your code, it's better to separate front presentation from back, so this function will be more logic to integrate to make others operations (of course it's not a big deal to modify)

ok it was a problem with directory which doesn't exist, the strnage is function doesn't stop and go to infinite recursive
another list function I found useful : http://www.webmaster-talk.com/php-forum/41811-list-files-in-directory-sub-directories.html

I just want to say thank you for the information.
It is very valuable for me..newbie here and encountering the same situation.
Thanks and keep up the good work..

The functions on this site did not work for me.
I wrote one myself.
It converts the directory structure into an array.
It returns some relevant data in the {data} key and loops through the rest.
It might not be the cleanest script but it does the job for me.
Maybe it helps someone.



//$include overrides $exclude. $include should be an array of file extensions eg. array("jpg", "png", "gif")
function readDirectory($path="./", $exclude=array(".", "..", ".htaccess"), $include=false){
$ds = "/";
if(!$path){ $path=$this->path;}
$return = array();
$return['{data}']['path'] = $path;
$return['{data}']['has_files'] = 0;
$return['{data}']['has_dirs'] = 0;

if(is_dir($path)){
$dir = opendir($path);
while ($file = readdir($dir)) {

if(is_dir($path.$ds.$file)){
if($file != "." && $file != ".."){
$return[$file] = array();
}
} else {
if(!$include){
if(!in_array($file, $exclude)){
$return['{data}']['files'][] = $file;
$return['{data}']['has_files'] = 1;
}
} else {
$ext = end(explode(".", $file));//GET FILE EXTENSION
if(in_array($ext, $include)){
$return['{data}']['files'][] = $file;
$return['{data}']['has_files'] = 1;
}
}
}

}
}
if(is_array($return)){

ksort($return);
if(isset($return['{data}']['files'])){
natcasesort($return['{data}']['files']);//SORT CASE INSENSETIVE
$return['{data}']['files'] = array_values($return['{data}']['files']);//REINDEX KEYS
}
foreach($return as $key => $value){
if(is_array($value)){
if($key != '{data}'){
$return['{data}']['has_dirs'] = 1;
$return[$key] = readDirectory($path.$key.$ds, $exclude, $include);
}
}
}
}
return $return;
}

thank for your code. but i want to call getDirectory() function with parameter like below example:
getDirectory("http://updatesofts.com");
does it work?
if not how to i can?
thanks.










privacy (GDPR)