Recursieve Directory Iterator - Doorloop mappen
Ik vind het zonde om te zien dat er nog zoveel mensen zijn die een map uit gaan lezen met fopen en readdir, terwijl er vanaf PHP 5 een prachtige klasse is waarmee je dat kunt doen. Hieronder dus een class met een recursieve functie, gebruik makend van de ingbouwde Directory Iterator classe om mappen door te lopen. Ik heb lang niet alle functies gebruikt die je kunt gebuiken. Enkele andere functies zijn: getPathname() - Geef het bestandspath met de filname getPath() - Geef het bestandspath zonder de filname getPerms() - Geef de permissies getSize() - Geef de bestandsgrote isExecutable() - Bekijk of het bestand uitvoerbaar is isReadable() - Bekijk of je rechten hebt het bestand te lezen isWritable() - Bekijk of je rechten hebt om naar het bestand te schrijven isFile() - Bekijk of het een bestand is (en dus geen map) isLink() - Bekijk of het een snelkoppeling is getATime() - Geef de tijd van de laatste toegang getOwner() - Geef de eigenaar van het bestand Mijn OOP stijl is niet geweldig, moet het allemaal nog wat door krijgen, maar daar gaat het hier niet om. Het gaat om het onder de aandacht brengen van de Directory Iterator
<?php
ini_set('display_errors',1);
error_reporting(E_ALL);
class file_list
{
public $aDir;
private $sDir;
private $aShow;
private $aHide;
function __construct($sDir, $aShow = null, $aHide = null)
{
$this->pDate_format = 'd-m-Y H:i:s'; //het formaat zoals de datum in de array zal worden gezet
$this->sDir = $sDir; //de opgegeven dir in een variabele in onze classe zetten
$this->aShow = $aShow;
$this->aHide = $aHide;
$this->read_dir(); //en de directory uit gaan lezen
}
//een functie waarmee we de extensie uit een bestandsnaam kunnen halen
function get_extension($sBestandsnaam)
{
if(strstr($sBestandsnaam, '.')) //wanneer er een . in de bestandsnaam staat
{
return end(explode('.', $sBestandsnaam)); //exploden we op de . en pakken we de laatste waarde
}
else //als er geen . in staat
{
return null; //dan kunnen we geen extensie geven
}
}
//Dit wordt onze recursieve functie om subdirectories uit te lezen
function read_sub_dir($sDir)
{
$aFiles = array();
try //we gaan het proberen
{
$oBestanden = new DirectoryIterator($sDir); //Door middel van het openen van de klasse worden alle bestand al opgehaald
foreach($oBestanden as $oBestand) //die kunnen we doorlopen met een foreach
{
if(!$oBestand->isDot()) //wanneer het bestand geen punt is (dus geen . (actuele map) of .. (bovenliggende map))
{
$sFilename = $oBestand->getFilename(); //dan zetten we de bestandsnaam in een variabele
if($oBestand->isDir()) //als het bestand een map is
{
$aFiles[$sFilename] = $this->read_sub_dir($oBestand->getPathname()); //dan gaan we deze uitlezen
}
elseif((is_array($this->aShow) && in_array($this->get_extension($sFilename), $this->aShow)) || //als de show array geset is, en het bestand komt hier in voor
(is_array($this->aHide) && !in_array($this->get_extension($sFilename), $this->aHide)) || //of de verberg array is geset en het bestand komt hier niet in voor
(!is_array($this->aHide) && !is_array($this->aShow))) //of beide arrays zijn niet geset
{
$aFiles[$sFilename] = array('filename' => $sFilename, //dan zetten we de bestandsnaam
'ext' => $this->get_extension($sFilename), //de extensie
'edit_time' => date($this->pDate_format, $oBestand->getMTime())); //en de tijd van de laatste bewerking in de array
}
}
}
ksort($aFiles); //dan nog even de bestanden sorteren
return $aFiles; //en we geven de bestanden terug
}
catch(Exception $e) //wanneer er iets fout is gegegaan hierboven
{
echo $e->getMessage(); //dan gooien we de error naar het scherm
}
}
//de functie hieronder werkt vrijwel hetzelfde als die hierboven, daarom voorzie ik hem niet van commentaar.
function read_dir()
{
try
{
$oBestanden = new DirectoryIterator($this->sDir);
foreach($oBestanden as $oBestand)
{
$sFilename = $oBestand->getFilename();
if(!$oBestand->isDot())
{
if($oBestand->isDir())
{
$this->aDir[$sFilename] = $this->read_sub_dir($oBestand->getPathname());
}
elseif((is_array($this->aShow) && in_array($this->get_extension($sFilename), $this->aShow)) ||
(is_array($this->aHide) && !in_array($this->get_extension($sFilename), $this->aHide)) ||
(!is_array($this->aHide) && !is_array($this->aShow)))
{
$this->aDir[$sFilename] = array('filename' => $oBestand->getFilename(),
'ext' => $this->get_extension($sFilename),
'edit_time' => date($this->pDate_format, $oBestand->getMTime()));
}
}
}
ksort($this->aDir);
}
catch(Exception $e)
{
echo $e->getMessage();
}
}
//dan maken we ook nog een functie waarmee wel een <ul> <li> structuur kunnen uitpoepen
function show_ulli($aBestanden = null)
{
$aBestanden = (!is_null($aBestanden) ? $aBestanden : $this->aDir); //als er geen array is meegegeven, dan gebruiken we de array van de functie hierboven
$sReturn = '<ul>';
foreach($aBestanden as $sKey => $file) //we gaan de array doorlopen
{
if((is_array($file) && empty($file['ext']))) //wanner het een array is, maar de "ext" key niet bestaat, is het een map
{
$sReturn .= '<li>'.$sKey.$this->show_ulli($file).'</li>'; //dus doen we de loop opnieuw voor die map
}
else //als het wel een array is en de "ext" key bestaat ook, dan is het een bestand
{
$sReturn .= '<li>'.$file['filename'].' ('.$file['ext'].' bestand) Laatst bewerkt op: '.$file['edit_time'].'</li>';
}
}
$sReturn .= '</ul>';
return $sReturn;
}
}
?>
[b]Voorbeeld van het gebruik:[/b]
<?php
$uitlezen = new file_list($_SERVER['DOCUMENT_ROOT']); //toon alle bestanden
echo $uitlezen->show_ulli(); //we gooien de <ul> <li> structuur op het scherm
echo '<pre>'.print_r($uitlezen->aDir, true).'</pre>'; //en voor de geïntereseerden ook nog de array die gegenereerd wordt.
$uitlezen = new file_list($_SERVER['DOCUMENT_ROOT'], null, array('php')); //Verberg alle php bestanden
echo $uitlezen->show_ulli();
$uitlezen = new file_list($_SERVER['DOCUMENT_ROOT'], array('php'), null); //Toon alleen php bestanden
echo $uitlezen->show_ulli();
?>
[b]Er is ook een ingebouwde Recursieve Directory. Deze is nog in ontwikkeling, maar toch een klein voorbeeldje daarvan:[/b]
<?php
$iDepth = 0;
$oBestanden = new RecursiveDirectoryIterator($_SERVER['DOCUMENT_ROOT']);
echo '<ul>';
foreach(($oRii = new RecursiveIteratorIterator($oBestanden, RecursiveIteratorIterator::SELF_FIRST)) as $oFile)
{
if($oRii->getDepth() > $iDepth)
{
echo str_repeat('<ul>', $oRii->getDepth() - $iDepth);
}
if($oRii->getDepth() < $iDepth)
{
echo str_repeat('</ul>', $iDepth - $oRii->getDepth());
}
echo '<li>'.$oFile->getFilename().'</li>';
$iDepth = $oRii->getDepth();
}
echo '</ul>';
?>
Reacties
0