[php5] smartdir : les itérateurs en php - lecture intelligente de répertoire

Soyez le premier à donner votre avis sur cette source.

Vue 7 635 fois - Téléchargée 321 fois

Description

J'ai décidé de montrer toute la puissance de la SPL (Standard PHP Library) et des itérateurs en PHP5.
Ce package est à personnaliser. Il permet la lecture récursive ou non de répertoire, en appliquant, ou non, des filtres.
FILTER_ON fait un filtre montrant uniquement les fichiers correspondant aux masques :
oSmartDir::FILTER_ON = 'php';
Va filtrer sur les fichiers contenant'php'.
oSmartDir::FILTER_ON = array ('php, 'html', 'js');
va filtrer sur les fichiers contenant php, html, ou js.

FILTER_OFF faut un filtre négatif :
oSmartDir::FILTER_OFF = 'php';
ne montrera que les fichiers ne contenant pas 'php'.
Peut aussi être un tableau de masques.

oSmartDir::DIr = false;
Ne lira pas les répertoire

oSmartDir::FILE = false;
ne montrera pas les fichiers

oSmartDir::RECURSE = false;
Ne lira pas récursivement.

On peut évidemment modifier ces filtres via la méthode myFilter::valid ()

Méthodes :
oSmartDir::getDir ();
permet simplement de récupérer l'itérateur pour l'arborescence définie via les filtres (ou non, d'ailleurs).
Plus tard, j'implémenterai de nouvelles méthodes "outils" : copie, déplacement etc...en tenant compte des filtres.
//////
J'ai mis une méthode copy ().
Attention, elle est effective sur le fichier d'exemple : le zip contient toute une arborescence. Le fichier exemple lit cette arbo avec divers filtres, pour donner quelques exemples, puis crée un répertoire copie/ dans lequel il copie toute l'arborescence, mais en ne prenan t en compte que les fichiers contenant 'php'.
//////

J'ai volontairement montré un package assez complexe...mais la lecture d'un répertoire de manière récursive peut se faire en 3 lignes grâce aux itérateurs :
<?php

$dir = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator('.'), true);

foreach ( $dir as $file ) {
echo str_repeat('-', $dir->getDepth()) . ' '.$file.'<br />';
}
?>
Essayez ce code : il va lire récursivement le répertoire courant (donc, avec ses sous-répertoires), tout en indentant en fonction de l'arborescence.
Si si...!

Source / Exemple :


<?php
/**

  • smartDir package
  • @author Johan Barbier <johan.barbier@gmail.com>
  • @version 20011120
  • /
/**
  • class myFilter
  • check active filters
  • RecursiveFilterIterator child
  • /
class myFilter extends RecursiveFilterIterator { /**
  • active filter ON (keep these)
*
  • @var mixed
  • /
private $mFilterOn; /**
  • active filter OFF (do not keep these)
*
  • @var mixed
  • /
private $mFilterOff; /**
  • iterator
*
  • @var iterator
  • /
private $it = null; /**
  • error message
*
  • @var string
  • /
const ERROR_NO_VALID_FILTER = '{__FILTER__} is not a valid setable filter'; /**
  • Constructor
*
  • @param iterator $it
  • @param mixed $mFilterOn
  • @param mixed $mFilterOff
  • /
public function __construct ($it, $mFilterOn, $mFilterOff) { parent::__construct ($it); $this -> it = $it; $this -> mFilterOn = $mFilterOn; $this -> mFilterOff = $mFilterOff; } /**
  • Function accept ()
  • returns true or false if the current element is accepted or not
*
  • @return boolean
  • /
public function accept () { if (!is_null ($this -> mFilterOn)) { if (!is_array ($this -> mFilterOn)) { $mPos = strpos ($this -> it -> getFileName (), (string)$this -> mFilterOn); if (false === $mPos) { return false; } } else { foreach ($this -> mFilterOn as $sFilter) { $mPos = strpos ($this -> it -> getFileName (), (string)$sFilter); if (false !== $mPos) { return true; } } return false; } } if (!is_null ($this -> mFilterOff)) { if (!is_array ($this -> mFilterOff)) { $mPos = strpos ($this -> it -> getFileName (), (string)$this -> mFilterOff); if (false !== $mPos) { return false; } } else { foreach ($this -> mFilterOff as $sFilter) { $mPos = strpos ($this -> it -> getFileName (), (string)$sFilter); if (false !== $mPos) { return false; } else { return true; } } return false; } } return true; } } /**
  • Class MyRecursiveDirectoryIterator
  • parent of main class, RecursiveDirectoryIterator child
*
  • /
class MyRecursiveDirectoryIterator extends RecursiveDirectoryIterator { /**
  • are dir valid
*
  • @var boolean
  • /
protected $bDir = true; /**
  • are files valid
*
  • @var boolean
  • /
protected $bFile = true; /**
  • filter ON (keep these)
*
  • @var mixed
  • /
protected $mFilterOn = null; /**
  • filter OFF (do not keep these)
*
  • @var mixed
  • /
protected $mFilterOff = null; /**
  • Recursive dir or not
*
  • @var boolean
  • /
protected $bRecurse = true; /**
  • props that can be set
*
  • @var array
  • /
protected $aCanBeSet = array ( 'FLAG', 'FILTER_ON', 'FILTER_OFF', 'DIR', 'FILE', 'PATH', 'RECURSE' ); /**
  • filter ON (keep these)
*
  • @var RecursiveDirectoryIterator class constant
  • /
protected $cFlag = 0; /**
  • path to be read
*
  • @var string (valid path)
  • /
protected $sPath; protected $sCreatedDir = null; /**
  • error messages
*
  • @var string
  • /
const ERROR_PATH_NOT_FOUND = '{__PATH__} has not been found'; const ERROR_PROP_NOT_SETABLE = '{__PROP__} is not a setable property'; const ERROR_BAD_PROP_VALUE = '{__VAL__} is not a correct value for {__PROP__}'; const ERROR_NO_BOOLEAN = '{__PROP__} value must be a boolean'; /**
  • getChildren will retrieve sub path
*
  • @return subiterator
  • /
public function getChildren () { $iSub = new self ($this -> getPathname ()); $iSub -> bDir = $this -> bDir; $iSub -> bFile = $this -> bFile; $iSub -> mFilterOn = $this -> mFilterOn; $iSub -> mFilterOff = $this -> mFilterOff; return $iSub; } /**
  • get current key
*
  • @return string
  • /
public function key () { return $this -> getPath (); } /**
  • get current file
*
  • @return string
  • /
public function current () { return $this -> getFileName (); } /**
  • is the current element valid or not
*
  • @return boolean
  • /
public function valid () { if (!is_null ($this -> sCreatedDir)) { if ($this -> current () === $this -> sCreatedDir) { return false; } } $oFilter = new myFilter ($this, $this -> mFilterOn, $this -> mFilterOff); if (true === parent::valid ()) { if (false === $oFilter -> accept ()) { if (false === $this -> isDir ()) { parent::next (); return $this -> valid (); } else { return true; } } if (false === $this -> bDir) { if (true === $this -> isDir ()) { parent::next (); return $this -> valid (); } } if (false === $this -> bFile) { if (true === $this -> isFile ()) { parent::next (); return $this -> valid (); } } return true; } return false; } /**
  • Setter
*
  • @param string $sProp
  • @param mixed $mVal
  • /
public function __set ($sProp, $mVal) { if (!in_array ($sProp, $this -> aCanBeSet)) { throw new Exception (str_replace ('{__PATH__}', $sProp, self::ERROR_PROP_NOT_SETABLE)); } switch ($sProp) { case 'FLAG' : if (!in_array ($mVal, array (parent::CURRENT_AS_FILEINFO, parent::KEY_AS_FILENAME, parent::NEW_CURRENT_AND_KEY, 0))) { throw new Exception (str_replace (array ('{__VAL__}', '{__PROP__}'), array ($mVal, $sProp), self::ERROR_PATH_NOT_FOUND)); } $this -> cFlag = $mVal; break; case 'FILTER_ON' : $this -> mFilterOn = $mVal; $this -> mFilterOff = null; break; case 'FILTER_OFF' : $this -> mFilterOff = $mVal; $this -> mFilterOn = null; break; case 'DIR' : if (!is_bool ($mVal)) { throw new Exception (str_replace ('{__PROP__}', $sProp, self::ERROR_NO_BOOLEAN)); } $this -> bDir = $mVal; break; case 'FILE' : if (!is_bool ($mVal)) { throw new Exception (str_replace ('{__PROP__}', $sProp, self::ERROR_NO_BOOLEAN)); } $this -> bFile = $mVal; break; case 'RECURSE' : if (!is_bool ($mVal)) { throw new Exception (str_replace ('{__PROP__}', $sProp, self::ERROR_NO_BOOLEAN)); } $this -> bRecurse = $mVal; break; case 'PATH' : if (!is_dir ($mVal)) { throw new Exception (str_replace ('{__PATH__}', $mVal, self::ERROR_PATH_NOT_FOUND)); } $this -> sPath = $mVal; break; } } } /**
  • Class oSmartDir
  • MyRecursiveDirectoryIterator child
*
  • /
class oSmartDir extends MyRecursiveDirectoryIterator { /**
  • Constructor
*
  • @param string $sPath (valid path)
  • /
const ERROR_COPY_FAILED = 'Failed to copy {__FROM__} to {__TO__}'; public function __construct ($sPath) { if (!is_dir ($sPath)) { throw new Exception (str_replace ('{__PATH__}', $sPath, self::ERROR_PATH_NOT_FOUND)); } $this -> sPath = $sPath; } /**
  • getDir will retrieve the asked directory
*
  • @return iterator
  • /
public function getDir () { parent::__construct ($this -> sPath, $this -> cFlag); if (true === $this -> bRecurse) { return new RecursiveIteratorIterator ($this, true); } else { return $this; } } public function copy ($sTo) { $aDir = $this -> getDir (); if (!is_dir ($sTo)) { mkdir ($sTo, '0755'); } $this -> sCreatedDir = $sTo; while ($aDir -> valid ()) { if ($aDir -> current () !== $sTo && !$aDir -> isDot ()) { if (!$aDir -> isDir ()) { if (!@copy ($aDir -> getPathName (), $sTo.'/'.$aDir -> getPathName ())) { throw new Exception (str_replace (array ('{__FROM__}', '{__TO__}'), array ($aDir -> getPathName (), $sTo.'/'.$aDir -> getPathName ()), self::ERROR_COPY_FAILED)); } } else { if (!@mkdir ($sTo.'/'.$aDir -> getPathName (), '0755')) { throw new Exception (str_replace (array ('{__FROM__}', '{__TO__}'), array ($aDir -> getPathName (), $sTo.'/'.$aDir -> getPathName ()), self::ERROR_COPY_FAILED)); } } } $aDir -> next (); } $this -> sCreatedDir = null; } } /**
  • STARTING EXAMPLES
  • /
try { $oDir = new oSmartDir ('.'); } catch (Exception $e) { echo $e -> getMessage (); } try { echo '<br /><strong>ALL NO RECURSIVE</strong><br />'; $oDir -> RECURSE = false; // no recursivity $aDir = $oDir -> getDir (); while ($aDir -> valid ()) { if ($aDir -> isDot ()) { $aDir -> next (); } $sHtml = ''; if ($aDir -> isDir ()) { $sHtml.= '<strong>'.$aDir -> current ().'</strong>'; } else { $sHtml.= '<em>'.$aDir -> current ().'</em>'; } $sHtml .= '<br />'; echo $sHtml; $aDir -> next (); } echo '<br /><strong>ALL</strong><br />'; $oDir -> RECURSE = true; // recursivity back to true $aDir = $oDir -> getDir (); while ($aDir -> valid ()) { if ($aDir -> isDot ()) { $aDir -> next (); } $sHtml = str_repeat ('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;', $aDir -> getDepth ()); if ($aDir -> isDir ()) { $sHtml.= '<strong>'.$aDir -> current ().'</strong>'; } else { $sHtml.= '<em>'.$aDir -> current ().'</em>'; } $sHtml .= '<br />'; echo $sHtml; $aDir -> next (); } echo '<br /><strong>ALL + fileSize</strong><br />'; $oDir -> RECURSE = true; // recursivity back to true $aDir = $oDir -> getDir (); while ($aDir -> valid ()) { if ($aDir -> isDot ()) { $aDir -> next (); } $sHtml = str_repeat ('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;', $aDir -> getDepth ()); if ($aDir -> isDir ()) { $sHtml.= '<strong>'.$aDir -> current ().'</strong>'; } else { $sHtml.= '<em>'.$aDir -> current ().' '.round (($aDir -> getSize()/1024), 2).' Ko</em>'; } $sHtml .= '<br />'; echo $sHtml; $aDir -> next (); } echo '<br /><strong>ALL</strong><br />'; $aDir = $oDir -> getDir (); foreach ($aDir as $sK => $sV) { echo str_repeat ('-----', $aDir -> getDepth()), $sK, ' => ', $sV, '<br />'; } echo '<br /><strong>FILTRE ON SUR PHP</strong><br />'; $oDir -> FILTER_ON = 'php'; // only shows files with "php" in them $aDir = $oDir -> getDir (); foreach ($aDir as $sK => $sV) { echo str_repeat ('-----', $aDir -> getDepth()), $sK, ' => ', $sV, '<br />'; } echo '<br /><strong>DIR = FALSE</strong><br />'; $oDir -> DIR = false; // No directory $oDir -> FILTER_ON = null; // no filter ON $aDir = $oDir -> getDir (); foreach ($aDir as $sK => $sV) { echo str_repeat ('-----', $aDir -> getDepth()), $sK, ' => ', $sV, '<br />'; } echo '<br /><strong>FILE = FALSE</strong><br />'; $oDir -> DIR = true; // show directories $oDir -> FILE = false; // No files $aDir = $oDir -> getDir (); foreach ($aDir as $sK => $sV) { echo str_repeat ('-----', $aDir -> getDepth()), $sK, ' => ', $sV, '<br />'; } echo '<br /><strong>PATH = bla ET FILTRE OFF SUR PHP</strong><br />'; $oDir -> PATH = 'bla'; // parth = 'bla' $oDir -> FILE = true; // show files $oDir -> FILTER_OFF = 'php'; // do not show files with "php" in them $aDir = $oDir -> getDir (); foreach ($aDir as $sK => $sV) { //echo $sK, ' => ', $sV, '<br />'; echo str_repeat ('-----', $aDir -> getDepth()), $sK, ' => ', $sV, '<br />'; } /**
  • Create a copy of the whole directory recursively, but ONLY copy files with php in them ;-)
  • /
$oDir -> FILTER_ON = 'php'; $oDir -> PATH = '.'; $oDir -> copy ('copie'); } catch (Exception $e) { echo $e -> getMessage (), ' => ', $e -> getLine (); } ?>

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
3
Date d'inscription
jeudi 27 juillet 2006
Statut
Membre
Dernière intervention
2 octobre 2007

Merci de ta réponse,

pour le moment je suis capable de récupérer la liste des fichiers se trrouvant direcetement dans ce répertoire(pas de recherche dans les sous dossiers en clair), mais mon besoin est différent je voudrais récupérer tous les fichiers depuis le répertoire que je spécifie (avec recherche dans les sous-dossiers donc)

Je voudrais donc savoir comment faire pour avoir une liste de tous les fichiers

merci encore
Messages postés
10840
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
21
Hello,
déjà merci:-)
Ensuite, je mets désormais la licence de mes codes, tellement cette question m'a été posée :-) Donc : LGPL.

Enfin...il ne devrait pas y avoir de problème particulièer quant à la racine du répertoire lu. Quand tu dis "je n'arrive pas à avoir une liste complète des fichiers uniquement depuis le répertoire source (en clair si mon répertoire source est C:\, je veux tous les fichiers de mon disque dur)", que vois tu au juste ? Tu en vois juste une partie? Tu ne vois rien ?
Messages postés
3
Date d'inscription
jeudi 27 juillet 2006
Statut
Membre
Dernière intervention
2 octobre 2007

Salut!

Je tiens premièrement à te féliciter pour ce code de qualité et pour l'utilisation avancé de la librairie SPL.

Dans mon projet j'utilise les différentes classes que tu partages ici, mais je bute sur un problème :

je n'arrive pas à avoir une liste complète des fichiers uniquement depuis le répertoire source (en clair si mon répertoire source est C:\, je veux tous les fichiers de mon disque dur)

existe-t-il une solution à mon problème ?

je voulais également savoir si ton code était sous une licence spécifique ou il s'agit d'un code totalement libre ?

Merci beaucoup pour tout ce travail c'est vraiment propre

bonne soirée

Cordialement
Messages postés
488
Date d'inscription
samedi 5 avril 2003
Statut
Membre
Dernière intervention
31 mars 2009
4
Non "au temps pour moi" :)
Messages postés
449
Date d'inscription
jeudi 26 août 2004
Statut
Membre
Dernière intervention
5 mars 2009

Ah heu.. autant pour moi ^^

@++
Afficher les 25 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.