homepage Welcome to WebmasterWorld Guest from 107.20.37.62
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




msg:4173842
 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




msg:4173868
 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




msg:4174202
 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




msg:4174235
 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




msg:4174420
 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




msg:4174437
 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




msg:4174517
 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




msg:4174541
 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




msg:4174787
 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




msg:4174883
 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




msg:4175073
 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




msg:4175459
 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




msg:4175755
 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




msg:4175828
 4:55 pm on Jul 24, 2010 (gmt 0)

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

Readie




msg:4175854
 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




msg:4176056
 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