homepage Welcome to WebmasterWorld Guest from 54.234.141.47
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member
Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
Forum Library, Charter, Moderators: coopster & jatar k

PHP Server Side Scripting Forum

    
Counting Files In A Directory
I think I'm close but still having trouble...
capulet_x

5+ Year Member



 
Msg#: 4173840 posted 6:19 am on Jul 21, 2010 (gmt 0)

I'm trying to list and count files in a directory and then echo back the results. The problem I'm having if the result seems to loop. The code I'm using is below. Can anyone help?

$dir = 'myfolder';
$files = scandir($dir);
foreach ($files as &$file) {
if ($file!='.' && $file!='..' )
{
while (list($key,$value) = each($files)) {
echo $key . $dir . $value
}
}
}

 

Matthew1980

WebmasterWorld Senior Member 5+ Year Member



 
Msg#: 4173840 posted 7:32 am on Jul 21, 2010 (gmt 0)

Hi there Capulet_x,

Something like this would be sufficient

$dir = 'myfolder';
$counter = array();
$i = "0";
$files = scandir($dir);
foreach ($files as &$file) {
if (($file != '.') && ($file!='..'))
{
$counter[] = $file[$i];
$i++;
}
}

echo count($counter);

Typed on the fly, but you get the idea. ( I think it's right anyway ;) )

Cheers,
MRb

rocknbil

WebmasterWorld Senior Member rocknbil us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4173840 posted 5:40 pm on Jul 21, 2010 (gmt 0)

What is happening is you are already looping through the files, then on each iteration you do a while on each file for the entire files array, an exponential loop (though not recursive, it will end eventually.) Good thing it didn't crash. :-)

You only need one loop. You don't need the file reference &, this is used when, if you change a variable's value, it will change outside of the scope of a function as well, or you want to "make a copy" of a variable and modify the copy without affecting the original variable value. Don't have to understand that at this point, just know you shouldn't need it for a loop iterator, it is a temporary variable. :-)


// Executable from **anywhere**
$dir = 'myfolder';
$files = scandir("$_SERVER[DOCUMENT_ROOT]/$dir");
echo "<ul>";
foreach ($files as $file) {
if ($file!='.' && $file!='..' ) {
// Or . . match on the extensions you want, more common
echo "<li>$dir/$file</li>";
}
}
echo "</ul>";

Matthew1980

WebmasterWorld Senior Member 5+ Year Member



 
Msg#: 4173840 posted 7:00 pm on Jul 21, 2010 (gmt 0)

Hi all,

Sorry about my original post, I'm not sure what I had had to drink before work this morning, but I just dug out a piece of code that will suit your needs, literally just counts the files in a specified directory and returns the numerical value - quite useful, though with a few tweeks from rocknbils suggestion this will do nicely :)

function ScanDirectory($DirList){
$DirRead = array();
$DirReadList = opendir($DirList);

//read specified directory & an store instances in array
while($DirGot = readdir($DirReadList)){
if(($DirGot != ".") && ($DirGot != "..")){
$DirRead[] = $DirGot;
}
}

return count($DirRead);
}



Hope that's a better suggestion for you - just pass the directory you want to scan into the function and it will echo the number of file like this:-

echo ScanDirectory("a_directory_to_scan/");


[EDIT]: Sorry I couldn't help myself, this is an amalgamation of mine and Rocknbils suggestions

function ScanCountList($dir){

$files = scandir($dir);

$counter = array();
$first = "<ul>";

foreach ($files as $file) {
if ($file!='.' && $file!='..' ) {
$counter[] = $file;
// Or . . match on the extensions you want, more common
$first .= "<li>$dir/$file</li>";
}
}
$first .= "</ul>";
return array($first,count($counter));
}

$Listings = ScanCountList('Your/path/to/directory/');

echo "File listing:-";
echo "<br>";
echo $Listings['0'];
echo "<br>";
echo "There are ".$Listings['1']." File".(($Listings['1'] > 1) ? '(s)':'')." in the Directory you specified";


That should do just nicely - and thanks to Rocknbil for giving me the idea too ;)

Cheers,
MRb

capulet_x

5+ Year Member



 
Msg#: 4173840 posted 1:27 am on Jul 22, 2010 (gmt 0)

Thanks so much for all of your effort and input. I tried some of the solutions here but I'm still not getting the output that I was looking for.
In my directory if I have 5 image files; for example:

dog.jpg
mouse.jpg
cat.jpg
tree.jpg
car.jpg

I would like the script to output:

1 dog.jpg
2 mouse.jpg
3 cat.jpg
4 tree.jpg
5 car.jpg

I would like the script to list the files and then prefix them with a corresponding number as above. Thats what I was trying to do with my original script but as rockinbil suggested my script created an exponential loop. I'm still trying to straighten it out.

rocknbil

WebmasterWorld Senior Member rocknbil us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4173840 posted 2:40 am on Jul 22, 2010 (gmt 0)

Same thing, just use OL?


$dir = 'myfolder';
$files = scandir("$_SERVER[DOCUMENT_ROOT]/$dir");
echo "<ol>";
foreach ($files as $file) {
if (preg_match('/\.jpe*g$/i',$file)) {
echo "<li>$dir/$file</li>";
}
}
echo "</ol>";


OR if you want a physical number, indices start at 0, so



$dir = 'myfolder';
$files = scandir("$_SERVER[DOCUMENT_ROOT]/$dir");
echo "<ul>";
$count = count($files);
for ($i=0;$i<$count;$i++) {
$num=$i+1;
if (preg_match('/\.jpe*g$/i',$file)) {
echo "<li>$num $dir/$file</li>";
}
}
echo "</ul>";


Note (I think) scandir is PHP5+ only, M's use of readdir is backwards compatible for older version.

capulet_x

5+ Year Member



 
Msg#: 4173840 posted 6:26 am on Jul 22, 2010 (gmt 0)

Thank you, rockinbil...
Although I still was not getting the output as I indicated above. I changed a few things that got me closer but now I'm getting another looping issue.

$dir = 'myfolder/';
$files = scandir("$dir");
$count = count($files);
for ($i=0;$i<$count;$i++) {
$num=$i+1;
foreach ($files as $file) {
if (preg_match('/\.jpe*g$/i',$file)) {
echo "<li>$num $dir/$file</li>";
}
}
}

This is the output I get:

1 myfolder/dog.jpg
1 myfolder/mouse.jpg
1 myfolder/cat.jpg
2 myfolder/dog.jpg
2 myfolder/mouse.jpg
2 myfolder/cat.jpg
3 myfolder/dog.jpg
3 myfolder/mouse.jpg
3 myfolder/cat.jpg
4 myfolder/dog.jpg
4 myfolder/mouse.jpg
4 myfolder/cat.jpg
5 myfolder/dog.jpg
5 myfolder/mouse.jpg
5 myfolder/cat.jpg
6 myfolder/dog.jpg
6 myfolder/mouse.jpg
6 myfolder/cat.jpg
7 myfolder/dog.jpg
7 myfolder/mouse.jpg
7 myfolder/cat.jpg
8 myfolder/dog.jpg
8 myfolder/mouse.jpg
8 myfolder/cat.jpg
9 myfolder/dog.jpg
9 myfolder/mouse.jpg
9 myfolder/cat.jpg

I think that the reason that it counted out to 9 was that there was a .gif file and a few .png files in the same folder as the jpegs. I would like it to output

1 myfolder/dog.jpg
2 myfolder/mouse.jpg
3 myfolder/cat.jpg

For some reason "$_SERVER[DOCUMENT_ROOT]" generated an error.

Matthew1980

WebmasterWorld Senior Member 5+ Year Member



 
Msg#: 4173840 posted 7:30 am on Jul 22, 2010 (gmt 0)

Hi there capulet_x,

function ScanCountList($dir){

$files = scandir($dir);

$counter = array();
$first = "<ol>";

foreach ($files as $file) {
if ($file!='.' && $file!='..' ) {
$counter[] = $file;
// Or . . match on the extensions you want, more common
$first .= "<li>$file</li>";
}
}
$first .= "</ol>";
return array($first,count($counter));
}

$Listings = ScanCountList('Your/path/to/directory/');

echo "File listing:-";
echo "<br>";
echo $Listings['0'];
echo "<br>";
echo "There are ".$Listings['1']." File".(($Listings['1'] > 1) ? '(s)':'')." in the Directory you specified";


That should output (I'm guessing the file names :)):-

1 cat.jpg
2 dog.jpg
3 rabbit.jpg
4 pig.jpg

ol will do the numbering for you, and I think that will do as you ask.

Rocknbil is absolutely right though PHP5 > is supportive of scandir - readdir is backwards compatible.

>>For some reason "$_SERVER[DOCUMENT_ROOT]" generated an error.

Worked fine for me :/ outside of the quotes it would need to be $_SERVER['DOCUMENT_ROOT']

Cheers,
MRb

capulet_x

5+ Year Member



 
Msg#: 4173840 posted 4:27 pm on Jul 22, 2010 (gmt 0)

Thank you, MRb...
I've been trying to work on a line by line counting method in php because I am not echoing inside the HTML body tags and so the <ol> tag does not function. It seems to be close now except for the looping.

rocknbil

WebmasterWorld Senior Member rocknbil us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4173840 posted 6:39 pm on Jul 22, 2010 (gmt 0)

Ok . . well . . . you don't need to echo, you can store it in a var and echo it wherever you want. You are partly correct on the number, but count() is also counting . and ..

You're getting dupes because you're looping in a loop, as you guessed. You only need one.


$dir = 'myfolder/';
$files = scandir("$dir");
$num = 0;
$file_list=null;

foreach ($files as $file) {
if (preg_match('/\.jpe*g$/i',$file)) {
$num++;
$file_list .= "<li>$num $dir/$file</li>";
}
}
if ($file_list) { $file_list = "<ol>$file_list</ol>"; }


You can remove that last line if you don't want to use OL, which is redundant if you're doing $num. At any rate you can put this wherever you want:

echo $file_list;

capulet_x

5+ Year Member



 
Msg#: 4173840 posted 12:02 am on Jul 23, 2010 (gmt 0)

Ahh...Now this worked brilliantly, Rocknbil ! The output was perfect! if I removed the "/\.jpe*g$/i" from preg_match will it read every file in the directory and include other types of image files such as .gif, .bmp, and .png or can I omit the entire line so that it reads every file in the directory?

rocknbil

WebmasterWorld Senior Member rocknbil us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4173840 posted 5:38 pm on Jul 23, 2010 (gmt 0)

If you want to read every file, check for file instead. But it's wisest to use the full path as I initially showed you. This should work.


$root = $_SERVER['DOCUMENT_ROOT'];
$dir = 'myfolder/';
$files = scandir("$dir");
$num = 0;
$file_list=null;
foreach ($files as $file) {
if (is_file("$root/$dir/$file")) {
$num++;
$file_list .= "<li>$num $dir/$file</li>";
}
}
if ($file_list) { $file_list = "<ol>$file_list</ol>"; }

Readie

WebmasterWorld Senior Member 5+ Year Member



 
Msg#: 4173840 posted 12:13 pm on Jul 24, 2010 (gmt 0)

$root = $_SERVER['DOCUMENT_ROOT'];

Just a note, it is, in my opinion, worth doing this like this:
$root = rtrim($_SERVER['DOCUMENT_ROOT'], "/");

As, depending on the server set up, document_root may or may not have a trailing slash. So, make sure there isn't one at all to keep your code portable.

rocknbil

WebmasterWorld Senior Member rocknbil us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4173840 posted 4:55 pm on Jul 24, 2010 (gmt 0)

Though I've never seen that, it would be worth the effort . . . :-)

Readie

WebmasterWorld Senior Member 5+ Year Member



 
Msg#: 4173840 posted 5:49 pm on Jul 24, 2010 (gmt 0)

The servers where I work have a trailing slash on root. My own personal one doesn't.

Caused a bit of annoyance when I was still doing free-lance projects from home :)

astupidname

5+ Year Member



 
Msg#: 4173840 posted 6:48 am on Jul 25, 2010 (gmt 0)

document_root may or may not have a trailing slash. So, make sure there isn't one at all to keep your code portable.

That is good advice, I've had the same troubles with the slash on end of $_SERVER['DOCUMENT_ROOT']. My localhost on WAMP has the slash at end of that, though my remote server does not, so I've always fixed it too.

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved