I am trying to understand part of the output I get from this code:
<?php
class DirectoryReader extends DirectoryIterator
{
function __construct($path)
{
parent::__construct($path);
}
function current()
{
return parent::getFileName();
}
function valid()
{
if(parent::valid())
{
if (!parent::isDir())
{
parent::next();
return $this->valid();
}
return TRUE;
}
return FALSE;
}
}
try
{
$it = new DirectoryReader('C:\wamp\www');
while($it->valid())
{
echo $it->current().'<br />';
$it->next();
}
}
catch(Exception $e)
{
echo 'No files Found!<br />';
}
?>
At the code you can see that I pass this path to the constructor: C:\wamp\www
,
What I don't understand: before I can see all the folders the first line is .
, the second is ..
, and then I can see the folder names for example:
.
..
someFolder
someOtherFolder
I know that .
present the current folder and ..
is getting back at the folders hierarchy, but I can't understand why does it print the .
then ..
and then the folders? I really want to understand the action of this iterator, if can some one please help me understand I will be very thankful.
The code parent::isDir()
returns TRUE
for the dot directories, meaning your own valid()
method returns TRUE
for them as well.
You could edit your method to look at whether isDot()
returns TRUE
or FALSE
and respond accordingly.
function valid()
{
return $this->isDir() && !$this->isDot();
}
That listing is correct, since .
and ..
are also (virtual) nodes in each directory. If you want to suppress the output of files/folder beginning with a dot (like Apache does in default configuration), you have to implement an appropriate check by yourself in valid()
in the given code.
When a directory is built, it is initially populated with the filename parts of two special files: the '.' and '..' files. The filename part for the '.' file is populated with the inode# of the directory file in which the entry has been made; '.' is a hardlink to the file that implements the current directory.
The filename part for the '..' file is populated with the inode# of the directory file that contains the filename part of the current directory file. '..' is a hardlink to the file that implements the immediate parent of the current directory.
It prints the . and .. because that class is only checking if the folder is a directory which both . and .. are
In case you do not want to show . and .. (as explained in other excellent answers) this snippet taken directly from the manual page comments.
Shows us all files and catalogues in directory except "." and "..".
<?php
foreach (new DirectoryIterator('../moodle') as $fileInfo) {
if($fileInfo->isDot()) continue;
echo $fileInfo->getFilename() . "<br>
";
}
Edit
The FilesystemIterator
is preferred, over the DirectoryIterator
. When using the former, the dot files are skipped by default (there is a flag to control this behaviour).
<?php
foreach (new FilesystemIterator('../moodle') as $fileinfo) {
echo $fileinfo->getFilename() . "<br>
";
}
furthermore the result is sorted, that's why '.' comes before '..' and 'some_other_directories'.