views:

3010

answers:

6

Is there a better/simpler way to find the number of images in a directory and output them to a variable?

function dirCount($dir) {
  $x = 0;
  while (($file = readdir($dir)) !== false) {
    if (isImage($file)) {$x = $x + 1}
  }
  return $x;
}

This seems like such a long way of doing this, is there no simpler way?

Note: The isImage() function returns true if the file is an image.

+6  A: 

Check out the Standard PHP Library (aka SPL) for DirectoryIterator:

$dir = new DirectoryIterator('/path/to/dir');
foreach($dir as $file ){
  $x += (isImage($file)) ? 1 : 0;
}

(FYI there is an undocumented function called iterator_count() but probably best not to rely on it for now I would imagine. And you'd need to filter out unseen stuff like . and .. anyway.)

bbxbby
That's what I was about to post. I think your solution is the way to go.
gaoshan88
AWSOME! Just what I was looking for!
PHLAK
A: 

Your answer seems about as simple as you can get it. I can't think of a shorter way to it in either PHP or Perl.

You might be able to a system / exec command involving ls, wc, and grep if you are using Linux depending how complex isImage() is.

Regardless, I think what you have is quite sufficient. You only have to write the function once.

Chris Kloberdanz
I try to avoid System and Exec (security first!), but I'll keep that in mind.
PHLAK
If you find that your isImage() function and current method is slow I think that doing a ls and piping it to wc -l might be faster. I would only do that IF your current method is slow though, because your right about the security reasons for not using system/exec.
GnomeCubed
+2  A: 

This will give you the count of what is in your dir. I'll leave the part about counting only images to you as I am about to fallll aaasssllleeelppppppzzzzzzzzzzzzz.

iterator_count(new DirectoryIterator('path/to/dir/'));
gaoshan88
lol nice one
+1  A: 

you could use glob...

$count = 0;
foreach (glob("*.*") as $file) {
    if (isImage($file)) ++$count;
}

or, I'm not sure how well this would suit your needs, but you could do this:

$count = count(glob("*.{jpg,png,gif,bmp}"));
nickf
A: 

You could also make use of the SPL to filter the contents of a DirectoryIterator using your isImage function by extending the abstract FilterIterator class.

class ImageIterator extends FilterIterator {

    public function __construct($path)
    {
     parent::__construct(new DirectoryIterator($path));
    }

    public function accept()
    {
     return isImage($this->getInnerIterator());
    }
}

You could then use iterator_count (or implement the Countable interface and use the native count function) to determine the number of images. For example:

$images = new ImageIterator('/path/to/images');
printf('Found %d images!', iterator_count($images));

Using this approach, depending on how you need to use this code, it might make more sense to move the isImage function into the ImageIterator class to have everything neatly wrapped up in one place.

salathe
A: 

The aforementioned code

$count = count(glob("*.{jpg,png,gif,bmp}"));

is your best best, but the {jpg,png,gif} bit will only work if you append the GLOB_BRACE flag on the end

pour examplé

$count = count(glob("*.{jpg,png,gif,bmp}", GLOB_BRACE));

Josh Dunbar