Fonction recursive de recherche de fichier selon une extension ou un groupe d'extension

Description

Ayant marre de voir des sources crades sur Code-sources et ayant l'opportunité de faire un code ces jours ci, je vous propose une manière de coder relativement propre (c'est ce que je pense ;) )

but :
permet de voir l'interet des expressions rationnelles ( ou régulières)
site interessant : http://qwix.media-box.net/index.php/2004/07/26/3-LesExpressionsRegulieresCompatiblesPerlEnPhpPartie1
montre ce qu'est une fonction récursive et comment en faire une
gestion des erreurs en fonction du retour de la fonction
intérêt d'un code bien commenté
le source n'a pas d'interet en lui meme a part de voir les points ennoncé plus haut

inconvénients :
utilisation de l'artillerie lourde pour un script simple

Définition :
fonction récursive :
fonction qui réalise une opération triviale ou dans le cas contraire s'appele elle-même afin de d'obtenir ce cas trivial

Source / Exemple :


fichier function/function.php

<?php

function takeFile( $_dir="" , $allowExtension=array() )
{

	// vérifie que les types des paramètres sont corrects

	if ( ! is_string( $_dir ) ){
		return -2 ; // erreur : $_dir n'est pas une chaine de caractere
	}

	if ( ! is_array( $allowExtension ) ){
		return -3 ; // erreur : $allowExtension n'est pas un tableau
	}

	// permet de garder les URL des images lors de l'appel récursif
	global $tabFile;

	if ( is_dir( $_dir ) ){
		if ( $dh = opendir( $_dir ) ) {

			/* définition des variables de travail */

			// détermine les répertoires à ne pas parcourir ( . et .. sont a proscrire car entraine un boucle infinie )
			$forbiddenDir = array( ".", ".." );

			// détermination du pattern permettant de récuperer les fichiers des extensions souhaité
			if ( count( $allowExtension ) > 0 ){
				foreach ( $allowExtension as $extension ){
					if ( ! isset( $listExtension ) ){
						$listExtension = "(\.".$extension;
					}else{
						$listExtension .= "|\.".$extension;
					}
				}
				$listExtension .= ')';
			}else{
				$listExtension = '';
			}

			// explication sur les patterns des expressions rationnelles
			//  #masque#option
			// (\w*) suite de 0,n caratère alphanumérique
			// i en option indique le fait que la recherche est insensible a la casse
			// | = OU logique
			$pattern = '#(\w*)'.$listExtension.'$#i';

		        // parcours tous les fichiers et répertoires courants du répertoire $_dir
	                while ( ( $file = readdir( $dh ) ) !== false ) {
                                // nom complet du fichier sinon is_dir ne marche pas (me suis déjà fait avoir)
				$completeFile = $_dir.'/'.$file;

				// lance la récursivité si et seulement si le fichier en cours est un dossier autorisé
				if ( is_dir( $completeFile ) and ! in_array( $file, $forbiddenDir ) ){
					takeFile($completeFile, $allowExtension);
				}elseif ( preg_match( $pattern, $file ) ){
					// ajout du chemin d'accès du fichier à tabFile
					$tabFile[] = $completeFile;
				}
	        }
	        closedir( $dh );
			return count( $tabFile ) - 1;
		}
	}else{
		return -4 ;// erreur : répertoire inexistant
	}
}
?>

// fichier de test ( permet d'afficher une image différente toutes les 3 secondes )
fichier index.php ( mais peut s'appeler un_nom.php )
<?php
session_start();

// permet le debugging a décommenter
// error_reporting( E_ERROR | E_WARNING | E_PARSE | E_NOTICE );

// mets un message d'erreur si le fichier n'existe pas + n'inclu qu'une fois le fichier
require_once "function/function.php";

/* définition des variables utiles au script */
// sert simplement à l'exemple : affichage d'une image toutes les 3 secondes

if ( ! isset( $_SESSION["i"]) ){
	$_SESSION["i"] = 1 ;
}else{
	$_SESSION["i"]++;
}

// détermine le répertoire où se situe le script
preg_match( "#/(\w*).php#", $_SERVER["SCRIPT_FILENAME"], $name ); // trouve le nom du script courant
$_dir = str_replace( $name[0], '', $_SERVER["SCRIPT_FILENAME"] );

// tableau des extensions autorisées
$allowExtension = array( "gif", "jpg", "jpeg", "bmp", "png" );

// exemple d'utilisation
$nb = takeFile( $_dir, $allowExtension);

?>
<html>
	<head>
		<?php
		// permet de rafraichir la page toutes les 3 secondes si le repertoire contient des images
		// gestion des erreurs
		switch ( $nb )
		{
			case -4 :
				$message = 'répertoire inexistant';
				break;
			case -3 :
				$message = '2nd paramètre incorrect';
				break;
			case -2 :
				$message = '1er parametre incorrect';
				break;
			case -1 :
				$message = 'aucune image dans les répertoires parcourus';
				break;
			default :
				// le modulo ( % ) permet d'avoir une valeur comprise entre 0 et le nombre d'image - 1
				$i = $_SESSION["i"];
				$_SESSION["i"] = ( $i % $nb ) ;
				// permet d'avoir l'adresse distante à la place de l'adresse physique
				$image = str_replace( $_SERVER["DOCUMENT_ROOT"], "http://".$_SERVER["HTTP_HOST"], $tabFile[$i] );
				$message = '<img src="'.$image.'" alt="'.$i.'"/><br />';
				echo '<meta content="3" http-equiv="refresh" />';
				break;
		}
		?>
	</head>
	<body>
		<?php

		/* définition des variables utiles au script */

		echo $message;

		// permet de vérifier si les résultats sont ceux attendus a décommenter pour vérifier
		// print_r( $tabFile );
		?>
	</body>
</html>

Conclusion :


Plus de bug connus,
Code fait à l'arrache donc il est surement optimisable
code HTML surement hors norme mais ce n'est pas le but (dès que j'ai 5 minutes je m'y attele)

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.