begin process at 2010 02 10 15:09:11
  Trouver un code source :
 
dans
 
Accueil > Forum > 

PHP

 > 

POO

 > 

Classes & Objets

 > 

DirectoryIterator, ma source est crade ?


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

DirectoryIterator, ma source est crade ?

vendredi 28 décembre 2007 à 15:30:28 | DirectoryIterator, ma source est crade ?

stailer

Bonjour,

je suis habitué à utiliser des Iterator et à en créer des simples... mais sur la classe DirectoryIterator je voudrais effectuer un tri.

Merci d'avance à ceux qui maitrisent très bien le sujet de me corriger si c'est pas bon (je ne parle pas des améliorations du code mais surtout de la METHODE de mon code) :

[code]
class OFDirectoryIterator extends DirectoryIterator
{
    private $tabRes;
    private $sort;
   
    const SORT_ASC = 'ASC';
    const SORT_DESC = 'DESC';
   
    public function __construct($path)
    {
        parent::__construct($path);
       
        $tabRes = array();
        foreach ($this as $file)
        {
            $myFile['isfile'] = $file->isFile();
            $myFile['filename'] = $file->getFilename();
               
            $this->tabRes[] = $myFile;
        }
    }
   
    private function alphaSort($a, $b)
    {
        if ($this->sort === SORT_ASC )
            return strcmp($a['filename'], $b['filename']);
        else
            return strcmp($b['filename'], $a['filename']);
    }
   
    public function setAlphaSort($constant_sort)
    {
        $this->sort = $constant_sort;
        usort($this->tabRes, array($this,'alphaSort'));
    }
   
    public function getResultIterator()
    {
        return $this->tabRes;
    }
   
}
[/code]

exemple d'utilisation :

[code]
$dir = new OFDirectoryIterator ($path);
$path->setAlphaSort(OFDirectoryIterator ::SORT_ASC);

foreach ($dir->getResultIterator() as $value)
{
  ...
}
[/code]

<--St@iLeR-->
vendredi 28 décembre 2007 à 17:07:10 | Re : DirectoryIterator, ma source est crade ?

neigedhiver

Salut, Je ne comprends pas pourquoi tu utilises strcmp pour trier ? Tu ne vérifies pas que l'argument de setAlphaSort a une valeur autorisée (l'une des constantes possibles). Je ne comprends pas comment tu utilises ton iterateur... En fait, ton itérateur, n'est pas utilisé pour itérer : il produit, avec la méthode getResultIterator() non pas un iterateur, mais un tableau. Je pense que tu ne fais pas ce qu'il faut. Ton itérateur n'itère pas : si on parcours l'objet avec foreach, on obtient les éléments, dans l'ordre naturel, c'est à dire dans l'ordre croissant. Si on veut réellement obtenir quelque chose de trié, il faut utiliser getResultIterator qui ne renvoit même pas ce qu'elle prétend : un Array au lieu d'un Iterator. La moindre des choses serait de renvoyer un ArrayIterator. Je pense que ton itérateur devrait permettre de réellement parcourir le répertoire par ordre décroissant. C'est lors du construct que tu devrais stocker les noms des fichiers dans ton tableau. Tu ne devrais pas non plus filtrer les fichiers réguliers, mais également laisser les liens et les répertoires, conformément au comportement d'orgine de DirectoryIterator. Il faut réécrire les méthodes de base de l'itérateur (next(), current(), rewind(), valid(), key() ) pour qu'elles utilisent le contenu du tableau. Alors seulement ton itérateur sera un vrai itérateur, avec tri croissant/décroissant.
vendredi 28 décembre 2007 à 19:02:59 | Re : DirectoryIterator, ma source est crade ?

malalam

Administrateur CodeS-SourceS
Hello,

Neige a raison : tu utilises la SPL et n'en tire finalement pas partie. Autant faire un sort($aDir = scandir('mondir')) ou pareil avec un rsort(), ça en revient au même et ce sera nettement plus optimisé.
Un itérateur, c'est fait pour se déplacer "ligne à ligne"...c'est un curseur. Imposer un ordre d'affichage à ce compte me parait curieux. Surtout sans index. A mon sens, il est intéressant de se pencher sur le problème et de trouver une parade sympa...mais je doute fort que ce soit réellement utile par contre. Ce serait juste un problème intéressant à résoudre. Tu ne pourras sans doute jamais obtenir un truc performant.
L'idée serait du coup en effet de redéfinir les méthodes d'iteration de base...par exemple, avec un filterIterator dynamique : il va filtrer sur l'élément le plus "bas" dans la hiérarchie, puis le stocke, puis cherche celui juste au-dessus, etc...mais c'est lourd.
Le strcmp() est, dans ce sens, une bonne idée justement. Mais pas utilisé ainsi.
Brefn l'idée est correcte, mais tu es hors du sujet que tu t'es imposé ;-) Tu ne fais pas de l'itération.
A la limite, tu peux ne pas utiliser un simple array() pour stocker ton répertoire, mais un ArrayIterator, qui lui implémente des méthodes de tri. Mais là, ça devient très simple ;-) Trop!


vendredi 28 décembre 2007 à 22:46:07 | Re : DirectoryIterator, ma source est crade ?

stailer

Oui c'était débile ,effectivement ça n'itere pas.

ceci dit, le code suivant ne serait il pas mieux tout de même :

<?php
function sortAlpha($a, $b)
{
    return strcmp($a['filename'],$b['filename']);
}

class OFDirectoryIterator extends ArrayObject
{
    private $compteur = 0;
   
    public function __construct($path)
    {
        $list = new DirectoryIterator($path);

        foreach ($list as $file)
        {
            $myFile['isfile'] = $file->isFile();
            $myFile['filename'] = $file->getFilename();
                   
            $this->append($myFile);
        }
       
        $this->ksort( 'sortAlpha');
       
    }
}
?>

exemple d'utilisation :
$iter = new OFDirectoryIterator($path);
       
foreach ($iter as $f) {
         echo $f['filename'].'<br/>';
 }

A terme, ce tableau serait remplacé pas un objet pour l'évolution de la classe, et de nouvelles méthodes "utilitaires" seraient intégrées.

ps: j'ai intégré le tri directement sur le constructeur mais bien entendu ça ne fonctionnera pas comme ça ... c'est juste pour avoir votre avis avant de continuer.

<--St@iLeR-->
vendredi 28 décembre 2007 à 23:31:19 | Re : DirectoryIterator, ma source est crade ?

neigedhiver

Re, Si tu veux faire un itérateur sur un répertoire, la meilleure classe à étendre, c'est vraiment DirectoryIterator. Pas ArrayObject. Ton itérateur OFDirectoryIterator va itérer sur un répertoire. La manière dont il itère dessus, tu vas la réécrire. Pour permettre de parcourir depuis la fin vers le début (tri décroissant), ton itérateur, puisqu'étant écrit en PHP et non en C dans l'extension SPL, devra gérer la liste avec sa propre méthode : via un tableau me parait tout à fait adapté. Certes, on y perd un peu en performances, du fait que tu parcours une première fois le répertoire pour récupérer les fichiers, stocker leur nom dans un tableau, trier le tableau avant d'itérer réellement comme on veut. N'empêche que l'intérêt de la classe est de permettre le tri suivant certains critères (ordre alphabétique, date de création, date de modification, nom de l'utilisateur propriétaire, etc : pourquoi ne trier que sur le nom ?) avec une syntaxe extrêmement lisible et facile à maintenir (et tant pis pour la double boucle !) Donc : - dans ton constructeur, tu parcours le répertoire et stockes les noms de fichiers dans un tableau. - dans ton constructeur, toujours, tu tries le tableau suivant le critère passé en argument - tu itères sur le tableau qui contient les éléments dans le bon ordre. Pour ne rien perdre des méthodes de DirectoryIterator, il faut que toutes celles-ci soient utilisables avec ta classe étendue (sinon, aucun intérêtà ta classe, on peut se contenter de tout faire soi-même : parcourir le répertoire, et stocker les fichiers dans un tableau, le trier, et afficher dans l'ordre qu'on veut. Pas besoin de classe pour faire juste ça. Si, par contre, on peut itérer sur le répertoire trié dans le sens qu'on veut et qu'on peut utiliser toutes les méthodes de DirectoryIterator (isFile(), isLink(), getADate(), etc) alors c'est VRAIMENT intéressant, en terme d'utilisation et de syntaxe. Quand je serai de retour chez moi, je reprendrai certainement ma dernière source pour y ajouter le tri... Je me rends compte que j'y ai ajouté des trucs sympa (à mes yeux en tout cas), mais j'avais oublié le tri...
vendredi 28 décembre 2007 à 23:46:40 | Re : DirectoryIterator, ma source est crade ?

stailer

Mais justement le but c'est de faire toutes sortes de tris.... Tu as vu ça : $this->ksort( 'sortAlpha');
c'est uniquement pour l'exemple, je vais bien évidemment faire des méthodes pour trier dans le  sens ou l'ou vent etc.

ensuite tu as vu :
    $myFile['isfile'] = $file->isFile();
    $myFile['filename'] = $file->getFilename();

le but c'est que ça devienne :
 $myFile = new MyFile();
  $myFile->isFile = $file->isFile();
    $myFile->Filename = $file->getFilename();
etc... avec des traitements spéciaux dans cette classe MyFile qui permettront de définir pleins d'autres choses (récupérer uniquement les images jpg par exemple.. enfin bref, une classe évolutive)

Donc pourquoi pas étendre de DirectoryIterator... mais pourquoi s'embêter à redéfinir toutes les méthodes de base alors qu'ArrayObject me semble bien adapter ,avec des méthodes internes pour le tri ?

<--St@iLeR-->
samedi 29 décembre 2007 à 00:11:06 | Re : DirectoryIterator, ma source est crade ?

neigedhiver

"Donc pourquoi pas étendre de DirectoryIterator... mais pourquoi s'embêter à redéfinir toutes les méthodes de base alors qu'ArrayObject me semble bien adapter ,avec des méthodes internes pour le tri ?" Parce que ArrayObject n'offre pas les méthodes de DirectoryIterator. Tu parcours un répertoire, pas un tableau. Tu veux stocker les données de l'itérateur dans un tableau, tu peux éventuellement utiliser un itérateur comme ArrayIterator ou ArrayObject, ton itérateur OFDirectoryIterator étant alors un wrapper pour cet itérateur. Jette un coup d'oeil aux tutos de malalam sur les Design Patterns. Jette aussi un oeil à ma classe de listing de répertoire... J'ai fait un Iterateur avec Filtres : je n'ai pas utilisé FilterIterator, parce que je ne pouvais pas étendre 2 classes : j'ai donc réécrit les méthodes de l'itérateur pour qu'il se comporte comme un FilterIterator, même si ce n'en est pas officiellement un. Bref. Quand on parcourt un répertoire, on aime avoir accès à toutes les informations que donne DirectoryIterator sur le fichier courant. ArrayObject peut te servir pour parcourir les noms de fichiers dans l'ordre que tu veux, comme Iterateur interne. Ainsi, tu bénéficies des fonctionnalités de chaque, en respectant la logique de programmation : tu itères sur un répertoire, pas sur un tableau...
samedi 29 décembre 2007 à 00:15:32 | Re : DirectoryIterator, ma source est crade ?

stailer

Tu parlais par exemple de la SPL... j'ai fait ça en vitesse :

class MyFile extends SplFileInfo
{

}

class OFDirectoryIterator extends ArrayObject
{
    function sortAlpha($a, $b) {
        return strcmp($a->getFilename(),$b->getFilename());
    }
   
    public function __construct($path)
    {
        $list = new DirectoryIterator($path);

        foreach ($list as $file)
        {
            $myFile = new MyFile($path.$file);
            $this->append($myFile);
        }
       
        $this->ksort($this,array('sortAlpha'));
    }
}

à partir de la je peux me faire des méthodes pour trier comme je veux il me semble
<--St@iLeR-->
samedi 29 décembre 2007 à 00:24:40 | Re : DirectoryIterator, ma source est crade ?

stailer

... ou faire un petit système qui permet au programmeur de trier commeil veut ;)

j'aurais donc :
1- toutes les infos possibles sur le fichier dans ma boucle
2 - tous les tris possibles avant d'exécuter ma boucle, et des tris 'spécifiques' que je pourrais ajouter à mon arrayobject

C'est un peu lourd ok, mais ça me semble plus simple qu'avec DirectoryIterator et plus intuitif à développer...
maintenant je me trompe peut-être
<--St@iLeR-->
samedi 29 décembre 2007 à 02:03:39 | Re : DirectoryIterator, ma source est crade ?

stailer

Voilà un début plus approfondi,et je trouve que c'est pas mal (j'ai changé ArrayObject par ArrayIterator) :

class OFDirectoryIterator extends ArrayIterator
{
    const SORT_ASC = 'ASC';
    const SORT_DESC = 'DESC';
   
    private $value1 = 'a';
    private $value2 = 'b';
   
    public function __construct($path)
    {
        $list = new DirectoryIterator($path);

        foreach ($list as $file) {
            $this->append(new SplFileInfo($path.$file)); }
    }
   
    function __call($method, $args = array())
    {
        if ($args[0] === self::SORT_DESC ) {
            $this->value1 = 'b';
            $this->value2 = 'a';
        }
   
        switch ($method) {
            case 'setSortAlpha':
            case 'setSortMTime':
                uasort($this, array(get_class($this), str_replace('set','',$method))); break;
        }
    }
   
    private function SortAlpha($a, $b) {
        return strcasecmp(${$this->value1}->getFilename(),${$this->value2}->getFilename());
    }

    private function SortMTime($a, $b)
    {
        if (${$this->value1}->getMTime() ===  ${$this->value2}->getMTime()) return 0;
           return (${$this->value1}->getMTime() > ${$this->value2}->getMTime()) ? -1 : 1;
    }
}


Exemple :
$files = new OFDirectoryIterator ($path);
$files->setSortAlpha(OFDirectoryIterator::SORT_DESC);
foreach ($files as $file)
{
  echo $file->getFilename().'<br/>';
}

Qu'en pensez-vous ?

1 2

Cette discussion est classée dans : code, filename, sort, tabres, directoryiterator


Répondre à ce message

Sujets en rapport avec ce message

Aide dans mon code! svp [ par erasor ] Hey tt le monde...Je débute en php,alors j'ai fait ce petit script(filelister) pour m'exercer:CODEwhile (($filename = readdir($dh)) !== false){if (($f code source d'une fonction fournie par PHP (sort())? [ par zoukozouko ] Salut!J'ai besoin de récupérer le code source de la fonction sort() fournie par php. Comment puis-je l'obtenir?Mon problème est le suivant : j'ai deux Récupérer la valeur d'un get [ par beegeezzz ] Salut tout le monde, J'essaie en fait de trier mes données de mes tableaux. Pour cela, j'ai changé le nom des champs du tableau en URL : [code]echo '< La fonction glob( ) [ par mymydu42 ] Bonjour, es ce que quelqu'un pourrait m'expliquer le fonctionnement de la fonction Glob.J'ai trouvé le code mais je ne sait pas ou le mettre et commen "images en dur" dans le code [ par bultez ] Bonjour à toutes et à tous,    on peut utiliser ( extrait et par exemple )$i = iVBORw0KGg....EOF;header("Content-type: image/png");echo base64_dec Voir le code PHP en HTML [ par marek_wit ] Bonjour ! J'ai une question , comment je peux travaile en php dans Dreamweaver et voir ma création comme en HTML Example PHP : Je ne vois pas les tabl a propos formulaire d'inscription avec le code [ par crestmen ] bjj'ai trouvé une difuclté dans le creation d'un formulaire avec un code de securité.j'ai suivi la methode que vous presenté mais ca nemarche pas.est- cryptographpie : problème :) [ par Kikuts ] Bonjour à tous !Un petit problème :Warning: Cannot modify header information - headers already sent by (o CORRESPONDANCE DU CODE <MAP><:MAP> HTML EN PHP [ par pilule ] Bonjour,je recherche la correspondance du code html en langage PHP,MerciPilule MsgBox de confirmation. [ par Nodoka ] Bonjour,     Je vous explique, mon projet était d'écrire un code permetant d'ajouter des imprimantes en local. Via des listes box la personne choisiss


Nos sponsors


Sondage...

CalendriCode

Février 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 1,076 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales