Gestion de fichiers avec la spl

Description

Voilà bien longtemps que je lis différentes choses à propose de la SPL dans ces pages et j'ai fini par retrousser mes manches et essayer de comprendre le fonctionnement de cet outil.
Déjà, pour ceux que ça intéresse d'en savoir plus, voilà un lien qui m'a bien aidé à démarrer : http://julien-pauli.developpez.com/tutoriels/php/spl/
Dans cette source, rien de bien transcendant, de quoi établir un listing complet d'un dossier et de ses sous-dossiers (fichiers inclus), possibilité d'appliquer des filtres, d'en ressortir un arbre HTML des dossiers et fichiers ou un Array type listing de fichiers.
Cette source est très basique mais je ne souhaitais pas aller plus loin pour le moment car mes connaissances de la SPL datent d'hier. Il y aura certainement des choses à corriger d'abord puis des fonctions à ajouter ensuite.
Merci aux grands gourous de nous donner leur avis (Malalam, Neigedhiver, ...) sur cette source qui souhaite apporter un peu de fraîcheur avec la SPL.
Merci d'éviter les réflexions du genre 'il vaudrait mieux mettre les noms des méthodes en anglais', ... c'est pas le but ici, hein !

---------------------------
Utilisation de la class et des fonctions présentent :

//--> On crée l'instance de la classe
$fichiers = new utilitaireFichiers('./');

//--> On définit un peu le style de l'arbre HTML.
$fichiers->arbreFichierDebut = "<li class='{class}'>{fichier} <span class='taille'>({taille})</span>\n";

//--> On filtre les fichiers pour ne garder que ceux qui sont d'une extension .css
$fichiers->filtreExtensions("css",true);

//--> On renvoie l'arbre HTML qui contient tous les dossiers mais seulement les fichiers css
echo $fichiers->arborescence();

//--> On reprend la liste complète
$fichiers->initListe();

//--> On ne sélectionne que les fichiers de type .js
$fichiers->filtreExtensions("js",true);

//--> On peut passer un deuxième filtre (ou plus). Ici pour n'afficher que les fichiers qui sont dans un dossier "module"
$fichiers->filtreRegExp("#/module/#i", 0, 0, 0, true);

//--> On récupère la liste des fichiers sous forme de tableau et on l'affiche pour contrôle
print_r($fichiers->arrayFichiers());

----------------------------------
A noter que j'utilise aussi ça pour la gestion de l'affichage de l'arbre :
$css = "<style type='text/css'>\n";
$css .= "ul {padding:0 0 10px 16px}\n";
$css .= "li.dossier {font-weight:bold}\n";
$css .= "li.fichier {font-weight:normal}\n";
$css .= "li .taille {font-size: 0.8em}\n";
$css .= "</style>\n";

Source / Exemple :


<?php

/*****************************************************
/*
/* Class de gestion des fichiers
/* Cette class permet pour le moment de gérer une liste de dossiers/fichiers grâce à la SPL
/* On peut y appliquer des filtres par extension de fichier et des filtres personnalisés
/* On peut retourner un arbre des dossiers en HTML ou une liste des fichiers dans un Array
/*
/* Cette class est dans un état basique et chacun peut le modifier à son grée. Le principe c'est 
/* que tout se passe en 3 temps
/* 1- On crée le pointeur principal et on récupère la liste complète des dossiers/fichiers
/* 2- On applique tous les filtres et les tris voulus
/* 3- On traite la liste obtenue, soit pour une récupération sous forme HTML, Array, ... , soit
/* pour appliquer des oppérations de suppression, renommage, ...
/*
/*****************************************************/

class utilitaireFichiers {
	
	private $racine;
	private $listeRacine;
	private $listeSelect;
	
	//--> Pour l'affichage de l'arbre HTML
	public $arbreDossierDebut	= "<ul>\n";
	public $arbreDossierFin		= "</ul>\n";
	public $arbreFichierDebut	= "<li>\n{fichier}\n";
	public $arbreFichierFin		= "</li>\n";
	
	/**

  • @brief création de la gestion des fichiers
  • @param $_racine chemin absolu ou relatif vers le dossier à gérer
  • /
public function __construct($_racine){ $this->racine = $_racine; $this->listeRacine = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->racine,RecursiveDirectoryIterator::KEY_AS_FILENAME), RecursiveIteratorIterator::SELF_FIRST); $this->listeSelect = $this->listeRacine; } /**
  • @brief gère l'affichage des dossiers/fichiers sous forme d'arbre avec les paramètres arbreDossierDebut, arbreDossierFin, arbreFichierDebut, arbreFichierFin
  • @return renvoie un arbre au format HTML
  • /
public function arborescence(){ $arbo = $this->arbreDossierDebut; $nivoAncien = $this->listeSelect->getDepth(); $typeAncien = ""; foreach ($this->listeSelect as $entry) { $nivoActuel = $this->listeSelect->getDepth(); if($nivoActuel < $nivoAncien || ($entry->isDir() && $nivoActuel == $nivoAncien)){ $boucle = $nivoAncien - $nivoActuel; if($typeAncien == "fichier") $boucle--; for($i=0;$i<=$boucle;$i++){ $arbo .= $this->arbreDossierFin . $this->arbreFichierFin; } } //--> Défini le type $type = $entry->isDir() ? "dossier" : "fichier"; //--> Calcul des valeurs $valeurs = array( "chemin" => $entry->getRealPath(), "fichier" => $entry->getFilename(), "taille" => $entry->getSize(), "class" => $type ); $chercher = array( "chemin" => "#{chemin}#i", "fichier" => "#{fichier}#i", "taille" => "#{taille}#i", "class" => "#{class}#i" ); //--> Création de la ligne d'affichage $arbo .= preg_replace($chercher, $valeurs, $this->arbreFichierDebut) . "\n"; //--> Si c'est un dossier et qu'il a des enfants, on ajoute le code de début de dossier if($type == "dossier" && $this->listeSelect->hasChildren()){ $arbo .= $this->arbreDossierDebut; } else { //--> Ajout de la fin de fichier $arbo .= $this->arbreFichierFin; } //--> Enregistrement du nivo actuel et du type $nivoAncien = $nivoActuel; $typeAncien = $type; } $arbo .= $this->arbreDossierFin; return $arbo; } /**
  • @brief reprend la liste complète des dossiers/fichiers
  • /
public function initListe(){ $this->listeSelect = $this->listeRacine; } /**
  • @brief filtrage des données ($this->listeSelect) avec une expression régulière. Possibilité de garder tous les dossiers
  • @param $_regex expression régulière
  • @param $_mode
  • @param $_flags
  • @param $_preg_flags
  • @param $_preservDir Mettre à true pour ne pas filtrer les dossiers. Permet ainsi de garder la structure des dossiers tout en filtrant les fichiers.
  • /
public function filtreRegExp($_regex, $_mode = 0, $_flags = 0, $_preg_flags = 0, $_preservDir = false){ if($_preservDir){ $this->listeSelect = new RegexIteratorPreservDir($this->listeSelect, $_regex, $_mode, $_flags, $_preg_flags); } else { $this->listeSelect = new RegexIterator($this->listeSelect, $_regex, $_mode, $_flags, $_preg_flags); } } /**
  • @brief Filtre les fichiers par leurs extensions. Fonction de facilité qui utilise en réalité le système de tri par RegExp
  • @param $_extensions Liste d'extensions séparées par des virgules. Ex: php,html,js
  • @param $_preservDir Mettre à true pour ne pas filtrer les dossiers. Permet ainsi de garder la structure des dossiers tout en filtrant les fichiers.
  • /
public function filtreExtensions($_extensions, $_preservDir = false){ $extensions = explode(",", $_extensions); $exp = "#\.(" . implode("|", $extensions) . ")$#i"; $this->filtreRegExp($exp, 0, 0, 0, $_preservDir); } /**
  • @brief fonction qui renvoie la liste des fichiers sous forme d'array
  • @return Array contenant la liste des chemins complets des fichiers
  • /
public function arrayFichiers(){ $fichiers = array(); foreach ($this->listeSelect as $entry){ if($entry->isFile()){ $fichiers[] = $entry->getRealPath(); } } return $fichiers; } } /**
  • @brief Class redéfinissant RegexIterator pour gérer la préservation des dossiers
  • /
class RegexIteratorPreservDir extends RegexIterator { public function __construct($_it, $_regex, $_mode = 0, $_flags = 0, $_preg_flags = 0){ parent::__construct($_it, $_regex, $_mode, $_flags, $_preg_flags); $this->regex = $_regex; $this->flags = $_flags; $this->mode = $_mode; $this->preg_flags = $_preg_flags; } /**
  • @brief On garde la fonction de base mais on ajoute la condition if($this->current->isDir())
  • /
public function accept(){ $matches = array(); $this->key = parent::key(); $this->current = parent::current(); if($this->current->isDir()){ return true; } else { $subject = ($this->flags & self::USE_KEY) ? $this->key : $this->current; switch($this->mode){ case self::MATCH: return preg_match($this->regex, $subject, $matches, $this->preg_flags); case self::GET_MATCH: $this->current = array(); return preg_match($this->regex, $subject, $this->current, $this->preg_flags) > 0; case self::ALL_MATCHES: $this->current = array(); return preg_match_all($this->regex, $subject, $this->current, $this->preg_flags) > 0; case self::SPLIT: $this->current = array(); preg_split($this->regex, $subject, $this->current, $this->preg_flags) > 1; case self::REPLACE: $this->current = array(); $result = preg_replace($this->regex, $this->replacement, $subject); if ($this->flags & self::USE_KEY){ $this->key = $result; } else { $this->current = $result; } } } } } ?>

Conclusion :


Quelques heures à étudier le fonctionnement de la SPL et déjà un bout de code fonctionnel. C'était pas si méchant que ça ... Je pense en avoir saisie une bonne partie. Pour le reste, des erreurs de fonctionnement sont peut-être à relever dans ce code. Merci aux experts de nous éclairer.

Codes Sources

A voir également

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.