windofo
Messages postés4Date d'inscriptiondimanche 22 novembre 2009StatutMembreDernière intervention18 décembre 2009
-
26 nov. 2009 à 12:02
windofo
Messages postés4Date d'inscriptiondimanche 22 novembre 2009StatutMembreDernière intervention18 décembre 2009
-
18 déc. 2009 à 10:01
Bonjour,
j'ai mis un peu le nez dans la lib SPL, et j'ai voulu m'inspirer du code source de malalam (j'en profite pour le remercier ainsi que tous les autres (neige, etc.) pour leurs nombreuses contributions)) pour faire un parcours de répertoire tout simple et j'avoue ne pas comprendre certain fonctionnement, entre les erreurs de segmentation et les dossiers répétés plusieurs fois je suis un peu perdu...
voici le code source:
class Dossier_RecursiveDirectoryIterator extends RecursiveDirectoryIterator {
/**
* affiche les dossiers
*
* @var boolean
*/
protected $bDir = true;
/**
* affiche les fichiers
*
* @var boolean
*/
protected $bFile = true;
/**
* filtrer les dossiers suivant une expression régulière
*
* @var string
*/
protected $sRegExpDir = '^.*$';
/**
* filtrer les fichier suivant une expression régulière
*
* @var string
*/
protected $sRegExpFile = '^.*$';
/**
* parcours recursif
*
* @var boolean
*/
protected $bRecurse = true;
/**
* propriétés qui peuvent être définies
*
* @var array
*/
protected $aCanBeSet = array (
'REGEXP_DIR',
'REGEXP_FILE',
'DIR',
'FILE',
'PATH',
'RECURSE'
);
/**
* path
*
* @var string (valid path)
*/
protected $sPath;
/**
* messages d'erreur
*
* @var string
*/
const ERROR_PATH_NOT_FOUND = '{__PATH__} n\'a pas été trouvé';
const ERROR_PROP_NOT_SETABLE = '{__PROP__} n\'est pas une propriété ';
const ERROR_BAD_PROP_VALUE = '{__VAL__} n\'est pas une valeur correcte pour la propriété: {__PROP__}';
/**
* getChildren
*
* @return subiterator
*/
public function getChildren () {
$iSub = new self ($this -> getPathname ());
$iSub -> bDir = $this -> bDir;
$iSub -> bFile = $this -> bFile;
$iSub -> sRegExpDir = $this -> sRegExpDir;
$iSub -> sRegExpFile = $this -> sRegExpFile;
return $iSub;
}
/**
* path
*
* @return string
*/
public function key () {
return $this -> getPath ();
}
/**
* retourne la valeur du fichier ou du dossier courant
*
* @return string
*/
public function current () {
return $this -> getFileName ();
}
/**
* vérifie si il y a un élément existant apres avoir appelé rewind() ou next().
*
* @return boolean
*/
public function valid () {
if (true === parent::valid ()) {
if (true === $this -> isDir ()) {
if (false === $this -> bDir || !preg_match ($this -> sRegExpDir, $this -> current())) {
$this -> next ();
return $this -> valid ();
} else {
return true;
}
} else {
if (false === $this -> bFile || !preg_match ($this -> sRegExpFile, $this -> current())) {
$this -> next ();
return $this -> valid ();
} else {
return true;
}
}
}
return false;
}
/**
* vérification des propriétés via la méthode magique __set
*
* @param string $sProp
* @param mixed $mVal
*/
public function __set ($sProp, $mVal) {
if (!in_array ($sProp, $this -> aCanBeSet)) {
throw new Exception (str_replace ('{__PROP__}', $sProp, self::ERROR_PROP_NOT_SETABLE));
}
switch ($sProp) {
case 'REGEXP_DIR' :
if (!is_string ($mVal)) {
throw new Exception (str_replace (array ('{__VAL__}', '{__PROP__}'), array ($mVal, $sProp), self::ERROR_BAD_PROP_VALUE));
}
$this -> sRegExpDir = $mVal;
break;
case 'REGEXP_FILE' :
if (!is_string ($mVal)) {
throw new Exception (str_replace (array ('{__VAL__}', '{__PROP__}'), array ($mVal, $sProp), self::ERROR_BAD_PROP_VALUE));
}
$this -> sRegExpFile = $mVal;
break;
case 'DIR' :
if (!is_bool ($mVal)) {
throw new Exception (str_replace (array ('{__VAL__}', '{__PROP__}'), array ($mVal, $sProp), self::ERROR_BAD_PROP_VALUE));
}
$this -> bDir = $mVal;
break;
case 'FILE' :
if (!is_bool ($mVal)) {
throw new Exception (str_replace (array ('{__VAL__}', '{__PROP__}'), array ($mVal, $sProp), self::ERROR_BAD_PROP_VALUE));;
}
$this -> bFile = $mVal;
break;
case 'RECURSE' :
if (!is_bool ($mVal)) {
throw new Exception (str_replace (array ('{__VAL__}', '{__PROP__}'), array ($mVal, $sProp), self::ERROR_BAD_PROP_VALUE));
}
$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 Dossier_Dir extends Dossier_RecursiveDirectoryIterator {
/**
* Itérateur
*
* @var iterator
*/
private $iterator = null;
/**
* messages d'erreur
*
* @var string
*/
const ERROR_NBR_ARG = 'Le nombre d\'arguments est incorrect';
const ERROR_TYPE_ARG = 'Le type d\'argument est incorrect';
/**
* Constructeur
*
*
* @param string $sPath (valid path)
*/
public function __construct ($sPath) {
if (!is_dir ($sPath)) {
throw new Exception (str_replace ('{__PATH__}', $sPath, self::ERROR_PATH_NOT_FOUND));
}
$this -> sPath = $sPath;
}
/**
* construction d'un itérateur du répertoire venant d'un chemin (string)
*
* @return iterator
*/
public function getDir () {
parent::__construct ($this -> sPath, 0);
if (true === $this -> bRecurse) {
$this -> iterator = new RecursiveIteratorIterator ($this, RecursiveIteratorIterator::LEAVES_ONLY);
} else {
$this -> iterator = $this;
}
return $this -> iterator;
}
/**
* ajout de filtres
* - addFilter ('filtre_1', 'val', 'filtre_2', true, etc.)
* - addFilter (array('filtre_1' => 'val', 'filtre_2' => true, etc.))
*
* @param mixed
*/
public function addFilter () {
$oArg = new ArrayObject (func_get_args ());
$it = $oArg -> getIterator ();
$numbArg = $it -> count ();
if ($numbArg > 1 && 0 == bcmod ($numbArg, 2)) {
while ($it -> valid ()) {
$prop = $it -> current ();
$it -> next ();
$val = $it -> current ();
if (is_string ($prop) && !empty ($prop)) {
$this -> $prop = $val;
$it -> next ();
} else {
throw new Exception (self::ERROR_TYPE_ARG);
}
}
} else if (1 == $numbArg) {
$aArg = $it -> current ();
if (is_array ($aArg) && !empty ($aArg)) {
foreach($aArg AS $prop => $val) {
if (is_string ($prop) && !empty ($prop)) {
$this -> $prop = $val;
} else {
throw new Exception (self::ERROR_TYPE_ARG);
}
}
} else {
throw new Exception (self::ERROR_TYPE_ARG);
}
} else if ($numbArg > 1) {
throw new Exception (self::ERROR_NBR_ARG);
}
}
}
et si je ne précise pas d'expression régulière j'ai en plus des résultats précédents plein de lignes avec des warnings
Warning: preg_match(): No ending delimiter '^' found in /Dossier/RecursiveDirectoryIterator.php on line 142
etc..
neigedhiver
Messages postés2480Date d'inscriptionjeudi 30 novembre 2006StatutMembreDernière intervention14 janvier 201119 30 nov. 2009 à 21:27
Salut,
Pourquoi utilises-tu une boucle while et pas une boucle foreach ? Foreach sert justement à itérer sur des tableaux, ou des objets implémentant Traversable. Foreach va automatiquement exécuter rewind(), valid(), next(), etc.
Avec ta boucle while(), tu cherches à reproduire le comportement de l'itération produite par foreach, mais je me demande si tu ne la reproduis pas avec une erreur qui expliquerait la duplication du premier répertoire.
Idem dans ta méthode addFilter()...
Sincèrement, utilise foreach() qui sert spécialement à l'itération, alors que while() pas du tout.
Concernant isDot(), par défaut, RecursiveDirectoryIterator ne tient pas compte des dossiers points. En tout cas, dans ma source (dont il me semble que tu t'es inspirée sur certains points), je ne m'occupe pas de isDot()...
Pour tes expressions réulières, le problème est qu'elles ne sont effectivement pas valides, comme l'indique le message d'erreur ;)
Du coup, je constate que tu exécutes à CHAQUE itération l'expression régulière... Si c'est pour tout laisser passer, je trouve dommage de bouffer des ressources en PCRE inutile...
--
Neige
Souvent la réponse à votre question se trouve dans la doc. Commencez par là ;)