Étiquette : php

  • Parcou­rir des dossiers et filtrer les fichiers n’a jamais été aussi simple avec la SPL de PHP5

    Parcou­rir les fichiers c’est simple avec PHP 5 et la SPL. Ou pas.

    <?php
     class bigFileFilterIterator extends FilterIterator {
         public function accept() {
             $oFileInfo = $this->getInnerIterator()->current();
             return ($oFileInfo->getSize() > 10000);
         }
     }
     $themedir = __DIR__.'/theme';
     $iterator = new RecursiveDirectoryIterator($themedir, FilesystemIterator::SKIP_DOTS);
     $iterator->setFlags(FilesystemIterator::CURRENT_AS_FILEINFO);
     $recursiveIterator = new RecursiveIteratorIterator($iterator);
     foreach(new bigFileFilterIterator($recursiveIterator) as $file) {
         echo $file->getfilename()."n";
     }

    Sérieu­se­ment ? Mais pourquoi ne puis-je pas utili­ser direc­te­ment le Recur­si­veDi­rec­to­ryI­te­ra­tor et dois-je instan­cier un Recur­si­veI­te­ra­torI­te­ra­tor ? Celui qui a conçu cette dernière classe souffre-t-il de bégaye­ment ? Rien que l’ins­tan­cia­tion du premier itéra­teur ne tient pas sur une seule ligne. Un ->getIn­nerI­te­ra­tor()->current() et pas un para­mètre direc­te­ment dans la méthode ->accept() ? Sérieu­se­ment ?

    Montrer les nouvelles possi­bi­li­tés c’est appré­ciable, les quali­fier de simple est une insulte à l’in­tel­li­gence.

    De mon temps on faisait quelque chose comme ce qui suit :

    <?php
     function recursive_filter($path) {
         $dir = dir($path) ;
         while (false !== ($name = $dir->read())) {
             if ($name[0] === '.') return ;
             $new_path = $path.DIRECTORY_SEPARATOR.$name ;
             if (is_dir($new_path)) {
                 recursive_filter($new_path) ;
             } elsif (file_size($new_path) > 10000) {
                 echo $new_path ;
             }
         }
     }
     $themedir = __DIR__.'/theme';
     recursive_filter( $themedir ) ;

    Ce n’était pas plus court, mais pas plus long. On peut entrer dans de longs discours pour savoir si c’était plus simple ou plus complexe, mieux struc­turé ou non, mais la valeur ajou­tée du nouveau code ne saute pas aux yeux côté simpli­cité je trouve.

    À titre d’exemple, en ruby (« find » est dans la lib stan­dard) :

    require 'find'
     theme_dir = File.dirname(__FILE__)."/theme"
     Find.find(theme_dir) do |path|
         next if FileTest.directory?(path)
         puts path if FileTest.size(path) > 10000
     end

    Ou sur Python :

    import os
     themedir = os.path.join(os.path.dirname(__file__), "theme")
     def find_files(directory):
       for root, dirs, files in os.walk(directory):
         for basename in files:
           if not file.startswith("."):
             filename = os.path.join(root, basename)
             yield filenames
     for filename in find_file(themedir)
       if os.path.getsize(filename) > 10000 :
         print filename

    Il peut y avoir des fautes et il peut y avoir mieux dans les diffé­rents langages, et peu importe le nombre de lignes, mais dans les quatre codes précé­dents c’est bien le premier qui me semble complexe.

    Il y a bien d’autres occa­sions de trou­ver PHP « simple », mais pas les itéra­teurs de la SPL.