...

View Full Version : please help me to count the number of folders with in directories



LJackson
10-05-2012, 04:28 PM
Hi All,

I am listing all the 'categories' with in a directory which is working now i want to try and find out the number of "folders" with in each of the category directories

here is my code

<?php
#get portfolio categories
if ($handle = opendir('portfolio'))
{
#echo "Directory handle: $handle\n";
#echo "Entries:\n";
$x = 1;
/* This is the correct way to loop over the directory. */
while (false !== ($entry = readdir($handle)))
{

#echo $entry;
if ($entry != "." && $entry != "..")
{

###count folders inside directorys
$directory = "portfolio/".$entry;
###end count folders inside directories


if (($x % 3) == 0)
{
$className = "col-2";
}
else
{
$className = "col-1";
}

?>
<div class="<?php echo $className?>">
<figure class="img-box">
<a href="portfolio-weddings.html">
<img src="images/page3-img1.jpg" alt="">
</a>
</figure>
<div class="gallery-meta">
<a href="#" class="gallery-name"><?php echo ucwords($entry);?></a>
<span class="capacity">(<?php echo $count; ?> Albums)</span>
</div>
</div><?php
$x++;
}
}

closedir($handle);
}?>

i've got up to the point of setting the individual categories now i need to figure out how to count the number of folders within these directories

can anyone help me please
thanks
Luke

Fou-Lu
10-05-2012, 04:32 PM
Do you need to count the subdirectories of the $directory, or the subdirectories of the $entry?

LJackson
10-05-2012, 04:40 PM
of the $directory :)

Fou-Lu
10-05-2012, 04:46 PM
I'd write a filter function and then use a scandir:


function filterArrayOnlyDirectories($itm)
{
$bResult = false;
if (is_dir($itm) && !in_array($itm, array('.', '..'))
{
$bResult = true;
}
return $bResult;
}

//. . .
$aItems = scandir($directory);
$aItemsFiltered = array_filter($aItems, 'filterArrayOnlyDirectories');

Now you can count the $aItemsFiltered. This could be done with recursive iterators as well.

LJackson
10-05-2012, 05:06 PM
ok thanks for the above,

i have added the function to my page and added these two lines in my while loop

$aItems = scandir($directory);
$aItemsFiltered = array_filter($aItems, 'filterArrayOnlyDirectories');

like so

#get portfolio categories
if ($handle = opendir('portfolio'))
{
#echo "Directory handle: $handle\n";
#echo "Entries:\n";
$x = 1;
/* This is the correct way to loop over the directory. */
while (false !== ($entry = readdir($handle)))
{

#echo $entry;
if ($entry != "." && $entry != "..")
{

#count folders inside directorys
$directory = "portfolio/$entry";
$aItems = scandir($directory);
$aItemsFiltered = array_filter($aItems, 'filterArrayOnlyDirectories');

if (($x % 3) == 0)
{
$className = "col-2";
}
else
{
$className = "col-1";
}

?>
<div class="<?php echo $className?>">
<figure class="img-box">
<a href="portfolio-weddings.html">
<img src="images/page3-img1.jpg" alt="">
</a>
</figure>
<div class="gallery-meta">
<a href="#" class="gallery-name"><?php echo ucwords($entry);?></a>
<span class="capacity">(<?php echo count($aItemsFiltered); ?> Albums)</span>
</div>
</div><?php
$x++;
}
}

closedir($handle);
}?>


i tried to echo out $aItemsFiltered and it returned 'array' so i then tried echo count($aItemsFiltered) and it always returns 0 even though at least on of my directories has a folder within it?

am i using it correctly? maybe my loop is incorrect?

cheers mate
Luke

kbluhm
10-05-2012, 05:15 PM
Another solution, once you have a folder path... this will count the number of folders immediately within that folder (non-recursive):


$sub_directories = glob( realpath( $directory ) . '/*', GLOB_ONLYDIR );
$sub_directories_count = count( $sub_directories );

Fou-Lu
10-05-2012, 05:20 PM
Sorry you'll need to verify its a directory before as well.


$directory = "portfolio/$entry";
if (is_dir($directory))
{
$aItems = scandir($directory);
$aItemsFiltered = array_filter($aItems, 'filterArrayOnlyDirectories');
}


As for debugging, the first step is to make sure that $aItems has directories within it. Perform a print_r($aItems); or a var_dump to make sure it has items within it. Then check that $aItemsFiltered also has data. If $aItems has data and $aItemsFiltered does not, make sure that the filterArrayOnlyDirectories function is within scope as an array_filter without a valid callback will always return false (and therefore have 0 results in the end).

I'm betting you do not have the function, unless you've modified it. I'd have a syntax error on this line: if (is_dir($itm) && !in_array($itm, array('.', '..')) since I'm missing a closing ).


Oh yeah I forgot that glob has an ONLYDIR directive! Wait, does that include the '.' and '..' as well?

LJackson
10-05-2012, 05:37 PM
i changed the function and added the missing ')' :)

ok i did some debugging

and
print_r($directories) echos out the directory paths.

print_r($aItems) echos out the following:

Array ( [0] => . [1] => .. [2] => New Text Document.txt [3] => New folder ) Array ( [0] => . [1] => .. ) Array ( [0] => . [1] => .. ) Array ( [0] => . [1] => .. ) Array ( [0] => . [1] => .. ) Array ( [0] => . [1] => .. )
this seems to be working correctly

print_r($aItemsFiltered) echos out:

Array ( ) Array ( ) Array ( ) Array ( ) Array ( ) Array ( )
this is obviously causing a problem as its returning an empty array

how does one make sure that the filterArrayOnlyDirectories function is within scope?

cheers

kbluhm
10-05-2012, 05:37 PM
Oh yeah I forgot that glob has an ONLYDIR directive! Wait, does that include the '.' and '..' as well?

No, they are excluded. :)

LJackson
10-05-2012, 05:45 PM
thanks kbluhm your solution works :)

would still like to get your method working fou-lu always nice to see different approaches to a problem

thanks guys

Fou-Lu
10-05-2012, 06:12 PM
Nice. I've been using iterators for so long I've forgotten about some of these more basic ones. And the globiterator itself let .'s into it depending on the flags.

To make sure its within scope, you simply add it to this page to be accessible or to a file that is included into this one. Sounds like its not in scope though since the original code would have thrown a fatal error since it would have had a syntactical error. Functions are global so long as they are not nested and are not a part of a class or namespace. Conditional branches also dictate if functions are available, so don't put it in an if condition.

LJackson
10-05-2012, 10:17 PM
thanks guys one more question if i may :)

if

$sub_directories = glob( realpath( $directory ) . '/*', GLOB_ONLYDIR );
$sub_directories_count = count( $sub_directories );

counts the folders/sub directories what d i need to change to make it count just the files within the directory not including any sub directories (not that there will be any) but files directly within the directory

many thanks
Luke

Fou-Lu
10-05-2012, 10:42 PM
There is no corresponding GLOB_ONLYFILE directive. However, so long as you have named extensions, then you can simply use a glob pattern of '/*.*'. If you don't have extensions, you'll need to make use of !is_dir.

Alternatively, you can pull a glob() of all records, and a glob of GLOB_ONLYDIR. Then you can use array_diff to remove the ones from the only directories glob from the entire glob which will leave you with only the files.
That should be doable as such (I can't test this where I am I'm afraid):


$sPath = realpath($directory) . '/*';
$aDirectories = glob($sPath, GLOB_ONLYDIR);
$aAll = glob($sPath);
$aFiles = array_diff($aAll, $aDirectories);

$aFiles should just be the files.

LJackson
10-05-2012, 11:28 PM
excellent thank you very much!!!

kbluhm
10-06-2012, 03:27 PM
Yet another alternative for your files vs. folders inquiry:


$glob = glob( realpath( $directory ) . '/*' );

// grab all files
$files = array_filter( $glob, 'is_file' );

// grab all folders
$dirs = array_filter( $glob, 'is_dir' );



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum