Directory listing script, need a little help...

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
deepsiks
Forum Newbie
Posts: 7
Joined: Sat Feb 18, 2006 5:32 am

Directory listing script, need a little help...

Post by deepsiks »

Hi all,
I've been using this script with no problems but recently I was asked if I could get the listings in alphabetical order. Any easy ideas?
Thanks, ds

Code: Select all

function direcho($path) 
		{global $filetotal, $totaldirs;	if ($dir = opendir($path)) 
		{while (false !== ($file = (readdir($dir)))) {

   		if (is_dir($path."/".$file)) {  

  		if ($file != '.' && $file != '..') {  

     		echo '<div class="folder">'.$file.''; 
		direcho($path."/".$file);
		echo "</div>";

     		$totaldirs++;}}	else {  
		$string = $path."/".$file;
		$bytes = filesize($string);
		$decimal = '2';
   		$position = 0;
     		$units = array( " Bytes", " KB", " MB", " GB", " TB" );
     		while( $bytes >= 1024 && ( $bytes / 1024 ) >= 1 ) {
        	$bytes /= 1024;
        	$position++;
     		}
     		$sizable = round( $bytes, $decimal ) . $units[$position];
		$creation = date ("M d Y H:i:s.", filectime($string));
		$string = rawurlencode($string);
		$string = str_replace("%2F", "/", $string);
		$extension = strtoupper(substr(strrchr($file, "."),1));
		echo '<div class="doc"><a href = '.$string.' target="window" title="'.$extension.' File, '.$sizable.', '.$creation.'">'.str_replace((strtolower(substr(strrchr($file, "."),0))), "", $file).'</a></div>';
		$filetotal++;}}closedir($dir);}}
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post by s.dot »

when you loop through the files, store them into an array, then run asort() on the array, loop through it and display the files
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
deepsiks
Forum Newbie
Posts: 7
Joined: Sat Feb 18, 2006 5:32 am

Post by deepsiks »

Could you give me an example?
phpkar
Forum Newbie
Posts: 4
Joined: Sat Feb 18, 2006 6:53 am
Contact:

Post by phpkar »

see this link
it is a Directory class , it may be usefull for you

http://www.php45.com/class.php?id=579
deepsiks
Forum Newbie
Posts: 7
Joined: Sat Feb 18, 2006 5:32 am

Post by deepsiks »

Thanks for the examples, they are giving me some ideas but my script gives me the output needed - except for the whole sorting thing. Is it possible to effectively patch my code to sort items or am I going to have to scrap it?
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

It actually should have been very clear from scrotaye's post. Can you try indenting the code in a better fashion (it might become clear then, reread his post)
deepsiks
Forum Newbie
Posts: 7
Joined: Sat Feb 18, 2006 5:32 am

Post by deepsiks »

Well, I rewrote portions of the script using asort but still had no luck and just got confused (not the best at php). Here's the solution I came up with:

Code: Select all

function direcho($path) { 
 	exec("ls -R $path",$f_list); $dir_str = $path; $filelist[0] = $path; $i = 1; 
 	for ($count=0; $count<count($f_list); $count++) { 
   	if ($f_list[$count] == "") { continue; } 
	if (substr($f_list[$count],strlen($f_list[$count])-1,1) == ":") 
	{$old_dir_str = $dir_str;
	$dir_str = substr($f_list[$count],0,strlen($f_list[$count])-1); 
	$back = (preg_match_all("/[\/]/", $old_dir_str, $matches)) - (preg_match_all("/[\/]/", $dir_str, $matches));
	$yt = 1; $back++;
	if ($back < 0)  { } else {while ($yt <= $back) { $filelist[$i] .= '</div>'; $yt++; }}
	$filelist[$i] .= '<div class="folder">'.(substr(strrchr($dir_str, "/"),1));      	
     	$i++; } else { 
     	$file_str = "$dir_str/$f_list[$count]"; 
     	if (is_file($file_str)) 
	{ $bytes = filesize($file_str); $decimal = '2'; $position = 0;
     	$units = array( " Bytes", " KB", " MB", " GB", " TB" );
     	while( $bytes >= 1024 && ( $bytes / 1024 ) >= 1 ) { $bytes /= 1024; $position++; }
     	$sizable = round( $bytes, $decimal ) . $units[$position];
	$creation = date ("M d Y H:i:s.", filectime($file_str));
	$file_nice = rawurlencode($file_str);
	$file_nice = str_replace("%2F", "/", $file_nice);
	$extension = strtoupper(substr(strrchr($file_nice, "."),1));
	$file_display = (substr(strrchr($file_nice, "/"),1));		
       	$filelist[$i] = '<div class="doc"><a href = '.$file_str.' target="window" title="'.$extension.' File, '.$sizable.', '.$creation.'">'.str_replace((strtolower(substr(strrchr($file_display, "."),0))), "", $file_display).'</a></div>';  
	$i++; }}}  return $filelist; }
I think the only drawback is it will be limited to unix machines. Could I have done this more gracefully?
-ds
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post by Maugrim_The_Reaper »

The PHP Manual provides an example for reading a directory using native PHP functions (no shell calls)

Code: Select all

<?php
// Note that !== did not exist until 4.0.0-RC2

if ($handle = opendir('/path/to/files')) {
   echo "Directory handle: $handle\n";
   echo "Files:\n";

   /* This is the correct way to loop over the directory. */
   while (false !== ($file = readdir($handle))) {
       echo "$file\n";
   }

   /* This is the WRONG way to loop over the directory. */
   while ($file = readdir($handle)) {
       echo "$file\n";
   }

   closedir($handle);
}
?>
You could adapt the above to detect whether a $file is a directory, and store these into an array.

Code: Select all

$dirlist = array();
if(is_dir($file))
{
    $dirlist[] = $file;
}
Now you would have an array of all directories. From there just sort the array alphabetically:

Code: Select all

asort($dirlist);

foreach($dirlist as $key=>$dirname)
{
    echo $dirname. '<br />';
}
deepsiks
Forum Newbie
Posts: 7
Joined: Sat Feb 18, 2006 5:32 am

Post by deepsiks »

Thanks, used the following but it won't recursively dive into the directorys...

Code: Select all

<?php
// Note that !== did not exist until 4.0.0-RC2
 $dirlist = array();
function dirlisting($path) { 
if ($handle = opendir($path)) {

   /* This is the correct way to loop over the directory. */
   while (false !== ($file = readdir($handle))) {
if ($file == "." or $file == "..") { } else echo "$file\n";
if(is_dir($file))
{
    $dirlist[] = $file;
} 

   }



   closedir($handle);
}

 asort($dirlist);

echo "<br>";
foreach($dirlist as $key=>$dirname)
{
if ($dirname == "." or $dirname == "..") { } else {
    echo "<B>".$dirname. '</b><br />';
 dirlisting($dirname);}
} }

dirlisting("./");

?>
Any suggestions?
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

Code: Select all

is_dir($path.$file)
or some variant thereof.
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post by s.dot »

Code: Select all

<?php 
// declare array for storing directory names
$dirlist = array(); 

// open the directory
$path = "path/to/dir/";
if($handle = opendir($path)){ 
	// loop through files 
	while(false !== ($file = readdir($handle))){ 
		if(($file != ".") && ($file != "..")){
			if(is_dir($path.$file)){
				// add the directory to our array
	 			$dirlist[] = $file;
 			}
		}
	}
	// close dir handle
	closedir($handle); 
}

// array $dirlist now has all directories stored in it
// so sort it alphabetically
asort($dirlist); 

// loop through the directory
// and echo them
foreach($dirlist as $dir){
	echo $dir."<br />";
}
?>
Something like that. I dunno if it works or not as I have not tested it. But that is the principle you want to build on. :). I did it so you can see how important indenting your brackets {} is to code readability. You won't be as confused if you develop a consistent style of indenting. :) And also, commenting your code helps too. Sometimes seeing it in english is better than seeing it in phpnglish.
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
deepsiks
Forum Newbie
Posts: 7
Joined: Sat Feb 18, 2006 5:32 am

Post by deepsiks »

Thanks!
deepsiks
Forum Newbie
Posts: 7
Joined: Sat Feb 18, 2006 5:32 am

Post by deepsiks »

I used the above and all worked out ok. Give me a listing of

Code: Select all

$path = "path/to/dir/";
What is the best way to dive in recursively?

Code: Select all

<?php 
// declare array for storing directory names
$dirlist = array(); 

// open the directory
$path = "./";
function Lister($path) {
	if($handle = opendir($path)){ 
	    // loop through files 
	    while(false !== ($file = readdir($handle))){ 
	        if(($file != ".") && ($file != "..")){
	            if(is_dir($path.$file)){
	                // add the directory to our array
	                 $dirlist[] = $file;
			}
	        }
	    }
	    // close dir handle
	    closedir($handle); 
	}
	
	// array $dirlist now has all directories stored in it
	// so sort it alphabetically
	asort($dirlist); 
	
	// loop through the directory
	// and echo them
	foreach($dirlist as $dir){
	echo $dir."<br />";
	    }
	}
Lister('./');
?>
I figure maybe just recall the function upon its self but I keep getting errors such as
Warning: asort() expects parameter 1 to be array, null given in /opt/lampp/htdocs/dirtest.php on line 24

Warning: Invalid argument supplied for foreach() in /opt/lampp/htdocs/dirtest.php on line 28
if I call the function like this

Code: Select all

// loop through the directory
	// and echo them
	foreach($dirlist as $dir){
	Lister($dir);
	    echo $dir."<br />";
	    }
I thought it work work like that, instead of just echoing the directory it would also recursively dive into it, but WRONG.
Am I making this just way to difficult?
Post Reply