Fonction listing d'un répertoire et création d'un lien

Bonjour,

Après plusieurs recherches sur le net, je suis arrivé à un code me permettant de lister tous les fichiers d’un répertoire et de les lister dans un tableau en les transformant en lien. Etant donné que je n’aurai que des fichiers PDF à lister, j’ai en plus rajouté une fonction forçant le téléchargement du fichier PDF.
Seul souci, pour cette dernière fonction, j’ai donc dans le répertoire à lister un fichier down.php…et celui-ci est listé dans le tableau alors qu’il ne faudrait pas. Pourtant, quand je lis les commentaires fait dans le code, il y a bien une fonction du code empêchant de lister les fichiers html et php…mais apparemment, ça ne fonctionne pas.
Quelqu’un pourrait m’aider à résoudre ce bug ?


<?php
function listing($repertoire){
	$fichier = array(); 
	if (is_dir($repertoire)){
		$dir = opendir($repertoire);                              //ouvre le repertoire courant désigné par la variable
		while(false!==($file = readdir($dir))){                             //on lit tout et on récupere tout les fichiers dans $file
			if(!in_array($file, array('.','..'))){            //on eleve le parent et le courant '. et ..'
				$page = $file;                            //sort l'extension du fichier
				$page = explode('.', $page);
				$nb = count($page);
				$nom_fichier = $page[0];
				for ($i = 1; $i < $nb-1; $i++){
					$nom_fichier .= '.'.$page[$i];
				}
				if($ext_fichier != 'php' and $ext_fichier != 'html') {        //utile pour exclure certains types de fichiers à ne pas lister
					array_push($fichier, $file);
				}
			}
		}
	}
	natcasesort($fichier);                                    //la fonction natcasesort( ) est la fonction de tri standard sauf qu'elle ignore la casse
	foreach($fichier as $value) {
			echo '<tr>
          <td><p align="center"><a href="'.rawurlencode($repertoire).'/down.php?pdf='.rawurlencode(str_replace ('/', '', $value)).'" target="_blank">'.$value.'</a></p></td>
        <td><p align="center">'.date ("d/m/Y", filectime($repertoire."/".$value)).'</p></td>
        </tr>';
	}
}
//exemple d'utilisation :
listing('winter');        //chemin du dossier
?>

Merci d’avance.

Résolu tout seul comme un grand :


<?php
//Guillaume ROBERT pour le site Zerobug
//http://www.zerobug.fr
//Script permettant de lister tous les fichiers PDF d'un répertoire
//dans un tableau et créant automatiquement des liens de 
//téléchargement. Le fichier PDF ne s'ouvre donc pas par défaut 
//dans le navigateur mais l'utilisateur aura le choix entre l'ouvrir
//et le télécharger sur son disque dur

function listing($repertoire){
	$fichier = array(); 
	if (is_dir($repertoire)){
		$dir = opendir($repertoire);                              //ouvre le repertoire courant désigné par la variable
		while(false!==($file = readdir($dir))){                             //on lit tout et on récupere tous les fichiers dans $file
			if(!in_array($file, array('.','..'))){            //on eleve le parent et le courant '. et ..'
				$page = $file;                            //sort l'extension du fichier
				$page = explode('.', $page);
				$nb = count($page);
				$nom_fichier = $page[0];
				for ($i = 1; $i < $nb-1; $i++){
					$nom_fichier .= '.'.$page[$i];
				}
				if(isset($page[1])){ 
                    $ext_fichier = $page[$nb-1]; 
                    if(!is_file($file)) { $file = ''.$file; }   //remplacer ''.$file par '/'.$file si besoin
                } 
                else { 
                    if(!is_file($file)) { $file = ''.$file; }   //remplacer ''.$file par '/'.$file si besoin
                    $ext_fichier = ''; 
                } 

				if($ext_fichier != 'php' and $ext_fichier != 'html') {        //utile pour exclure certains types de fichiers à ne pas lister
					array_push($fichier, $file);
				}
			}
		}
	}
	natcasesort($fichier);                                    //la fonction natcasesort( ) est la fonction de tri standard sauf qu'elle ignore la casse
	foreach($fichier as $value) {
	
	/* à partir de là, on créé le lien forçant le
	//téléchargement du fichier PDF
	//Pour cela, il vous faudra créer dans chaque répertoire à lister
	//un fichier php (ici nommé down.php) composé comme ceci :
	//<? 
    //header("Content-type: application/pdf"); 
    //header("Content-Disposition: attachment; filename=$pdf"); 
    //readfile($pdf); 
    //?> */
			echo '<tr>
          <td><p align="center"><a href="'.rawurlencode($repertoire).'/down.php?pdf='.rawurlencode(str_replace ('/', '', $value)).'">'.$value.'</a></p></td>
        <td><p align="center">'.date ("d/m/Y", filectime($repertoire."/".$value)).'</p></td>
        </tr>';
	}
}
//exemple d'utilisation :
listing('winter');        //chemin du dossier
?>

Edité le 29/09/2007 à 18:03

J’ai plusieurs remarques concernant ton code :

Si tu travaille en PHP5, le plus simple est d’utiliser la fonction scandir qui te permet de lister le contenu d’un dossier tout en effectuant un tri alphabétique. Tu pourra alors facilement extraire la liste des fichiers pdf que tu souhaites à partir de ce tableau.

Si tu souhaites continuer à utiliser ta fonction, je trouve que ta façon de séparer le nom du fichier de son extension est un peu du bricolage (d’ailleurs la variable $ext_fichier n’est jamais assigné dans ton premier message d’où le bug que tu cherches)

Tu as a disposition les fonctions suivantes pour effectuer ce traitement :

La fonction pathinfo
La fonction strrchr afin de trouver la dernière occurence du “.” et de prendre ce qui suit (qui est plus rapide que d’utiliser pathinfo pour l’opération que l’on souhaite faire ici)

De plus, il est documenté comme étant préférable pour ajouter un élément dans un tableau d’utiliser la synthaxe

$my_array[] = $my_var;

que passer par une fonction (en l’occurence ici array_push)

Voilà quelques pistes pour t’aider et améliorer la lisibilité et la performance de ton code :slight_smile:

Ps:

Voila comment je ferai ceci dans un premier jet :


<?php

function listing($dir)
{
   $pdf_files = array();
   $dh            = opendir($dir);

   while (false !== ($filename = readdir($dh)))
   {
        if(strtolower(strrchr($filename, '.')) == '.pdf')
             $pdf_files[] =  $filename;
   }
  
  //Si tu souhaite trier le tableau de résultat
  sort($pdf_files);

  foreach($pdf_files as $pdf_file)
  {
       //echo du lien
  }

}


?>

Edité le 29/09/2007 à 18:04

Ah ben ouais…de suite…même résultat en beaucoup plus court !
Merci.
Possible de trier en sens inverse de façon à ce que les derniers fichiers soient en haut du tableau ?
Et tu aurais une solution pour remplacer mon listing(‘winter’); ?

winter est le répertoire à anaylser, mais à chaque fois, la page php qui comporte ce code aura le même nom que le répertoire.
Donc, pour le dossier winter, j’utilise winter.php3 où se trouve le code ci-dessus.
J’ai pas mal testé de trucs…mais je n’y arrive pas !
Edité le 29/09/2007 à 18:10

Au lieu d’utiliser la fonction sort() tu peux utiliser la fonction rsort() qui effectue un trie dans l’ordre inverse

Tu as plein de solutions :

Il existe la constante magique FILE ("magique "car sa valeur peut changer au cours du script (par exemple si on passe dans un include), ce qui n’est pas normalement le cas avec une constante). Cette constante indique le chemin vers le fichier php en cours d’exécution. Tu peux donc récuperer le nom de ton fichier php à partir de sa valeur

Tu peux utiliser la super globale $_SERVER[‘PHP_SELF’] qui te donne le chemin du fichier par rapport a la racine de l’url ou encore utiliser $_SERVER[‘SCRIPT_FILENAME’] qui te donnera le chemin absolu vers le fichier en cours d’exécution.

Tu peux utiliser aussi $_SERVER[‘SCRIPT_NAME’] qui donne le nom du fichier avec son extension en cours d’exécution (à toi d’y enlever l’extension dans ce cas de la manière que tu souhaites)

Par exemple ceci devrai marcher et retourner la même valeur (le nom du fichier php sans l’extension que tu appelle ensuite avec ta fonction listing()) (a toi de tester pour vérifier) :


<?php

$path_parts = pathinfo(__FILE__); echo $path_parts['filename'];
$path_parts = pathinfo($_SERVER['SCRIPT_FILENAME']); echo $path_parts['filename'];
$path_parts = pathinfo($_SERVER['SCRIPT_NAME']); echo $path_parts['filename'];
$path_parts = pathinfo($_SERVER['PHP_SELF']); echo $path_parts['filename'];

?>

Edité le 29/09/2007 à 19:08

En utilisant ceci :
$path_parts = pathinfo(FILE); echo $path_parts[‘filename’];

Il faut donc ensuite que je fasse ceci :

listing($path_parts); ???

Car ça ne marche pas !

Plutot ceci :



$path_parts = pathinfo(__FILE__);

listing($path_parts['filename']);


car dans ton code tu passes tout le tableau en argument, on a juste besoin d’une valeur de ce tableau (ici celle a l’index ‘filename’)

Non, ça ne fonctionne pas :
Warning: readdir(): supplied argument is not a valid Directory resource in /home.3/zerobug/www/gestion/winter.php3 on line 68

A la ligne 68, j’ai ça :
while (false !== ($filename = readdir($dh)))

Que vaut $path_parts[‘filename’] ? SI ton fichier s’apelle winter.php3, sa valeur devrai etre ‘winter’



$path_parts = pathinfo(__FILE__);

echo $path_parts['filename']; //devrait t'afficher winter 

listing($path_parts['filename']); //si cela t'a afficher winter c'est comme si tu avait appelle ta fonction comme précédemment (listing('winter'))


Si tu as bien winter d’afficher, après c’est un problème d’emplacement de ton dossier winter : il faut que tu lui indiques dans ce cas son préfixe : par exemple :

listing($_SERVER[‘DOCUMENT_ROOT’].’/gestion/’.$path_parts[‘filename’]); si ton dossier winter est ici :

/home.3/zerobug/www/gestion/winter
Edité le 29/09/2007 à 19:28

Je n’arrive pas à avoir de donnée !

J’ai testé, et ca marche bien. Voici le code que j’ai utilisé :


function listing($dir)
{
	$pdf_files = array();
	$dh = opendir($dir);

	while (false !== ($filename = readdir($dh)))
	{
		if(strtolower(strrchr($filename, '.')) == '.pdf')
			$pdf_files[] = $filename;
	}
	 
	//Si tu souhaite trier le tableau de résultat
	sort($pdf_files);

	foreach($pdf_files as $pdf_file)
	{
		echo $pdf_file;
	}
}

$path_parts = pathinfo(__FILE__);

listing($_SERVER['DOCUMENT_ROOT'].'/'.$path_parts['filename']);

J’ai lancé ce script a partir de index.php, j’ai au meme niveau que le fichier index.php un repertoire “index” qui contient qq fichiers pdf et j’ai bien le listing de mes fichiers

Etant donné que mon dossier “index” est dans le meme repertorie que “index.php” je peux ecrire :

listing($path_parts['filename']);

ce qui me donne le même résultat
Edité le 29/09/2007 à 19:38

Bon, ça ne veut pas chez moi. Voilà le code complet que j’ai :


<?php
//Guillaume ROBERT pour le site Zerobug
//http://www.zerobug.fr
//Script permettant de lister tous les fichiers PDF d'un répertoire
//dans un tableau et créant automatiquement des liens de 
//téléchargement. Le fichier PDF ne s'ouvre donc pas par défaut 
//dans le navigateur mais l'utilisateur aura le choix entre l'ouvrir
//et le télécharger sur son disque dur

function listing($dir)
{
 $pdf_files = array();
 $dh = opendir($dir);

 while (false !== ($filename = readdir($dh)))
 {
 if(strtolower(strrchr($filename, '.')) == '.pdf')
 $pdf_files[] = $filename;
 }
 
 rsort($pdf_files);

 foreach($pdf_files as $pdf_file)
 {

	
	/* à partir de là, on créé le lien forçant le
	//téléchargement du fichier PDF
	//Pour cela, il vous faudra créer dans chaque répertoire à lister
	//un fichier php (ici nommé down.php) composé comme ceci :
	//<? 
    //header("Content-type: application/pdf"); 
    //header("Content-Disposition: attachment; filename=$pdf"); 
    //readfile($pdf); 
    //?> */
			echo '<tr>
          <td><p align="center"><a href="'.rawurlencode($dir).'/down.php?pdf='.rawurlencode(str_replace ('/', '', $pdf_file)).'">'.$pdf_file.'</a></p></td>
        <td><p align="center">'.date ("d/m/Y", filectime($dir."/".$pdf_file)).'</p></td>
        </tr>';
	}
}
$path_parts = pathinfo(__FILE__);

listing($path_parts['filename']);
?>

Résultat : Warning: readdir(): supplied argument is not a valid Directory resource in /home.3/zerobug/www/gestion/winter.php3 on line 67


le fait que mon fichier se nomme winter.php3 et non winter.php pourrait-il jouer ?

Vérifie la valeur de

$path_parts[‘filename’]

avec


$path_parts = pathinfo(__FILE__);
echo $path_parts['filename'];
//listing($path_parts['filename']);

Si tu n’a pas “winter” d’afficher le problème vient de là.

Si tu a winter tente d’écrire :


$path_parts = pathinfo(__FILE__);
listing($_SERVER['DOCUMENT_ROOT'].'/gestion/'.$path_parts['filename']);

Non, winter ne s’affiche pas…
Je viens de tenter aussi ton second code, ça ne marche pas non plus.:frowning:

SI winter ne s’affiche pas ta constante FILE n’est pas ok.

Essaye avec a la place $_SERVER[‘SCRIPT_NAME’] ou $_SERVER[‘SCRIPT_FILENAME’] (cf post plus haut les 4 manieres)


$path_parts = pathinfo($_SERVER['SCRIPT_NAME']);
echo $path_parts['filename'];

y’a t’il winter affiché ?
Edité le 29/09/2007 à 20:09

$path_parts = pathinfo($_SERVER[‘SCRIPT_NAME’]);
listing($_SERVER[‘DOCUMENT_ROOT’].’/gestion/’.$path_parts[‘filename’]);

Ca ne marche pas non plus…par contre, plus d’erreur à l’affichage, mais tableau vide.

Idem avec $_SERVER[‘SCRIPT_FILENAME’]

Petite question afin de simplifier si possible le code.
Pour le moment, j’ai ce code :

			echo '<tr>
 <td><p align="center"><a href="'.rawurlencode($dir).'/down.php?pdf='.rawurlencode(str_replace ('/', '', $pdf_file)).'">'.$pdf_file.'</a></p></td>
 <td><p align="center">'.date ("d/m/Y", filectime($dir."/".$pdf_file)).'</p></td>
 </tr>';

Il permet de forcer le téléchargement grâce à une entête spécifique dans down.php mais cela m’oblige à copier le fichier dans chque dossier où j’aurais des fichiers à télécharger (un dossier par client). N’y aurait-il pas moyen de modifier le code afin que je puisse laisser down.php à la racine ?