Page 1 sur 1

scan listage descendant à partir d'un répertoire donné

Posté : 26 mars 2009, 01:09
par Megadeth
Hi !

Le temps me manque et non l'envie (loin de là) et d'autres développeurs m'ont souvent dit qu'il ne fallait pas réinventer la roue...

Je cherche un moyen à partir d'un dossier de scanner tout son contenu (fichiers et sous-dossiers) que je puisse descendre jusqu'au dernier point sans jamais pouvoir remonter au dessus de mon point de départ, vous voyez le rendu. Une sorte de ftp phpïsé :)

Exemple : http://ludivine.gouel.free.fr/site/

pouvoir descendre mais pas remonter à l'accueil.

J'ai bien ceci :
      <?php 
	  $dos = "mon_dossier/";
      if ($handle = opendir($dos)) {
          while (false !== ($file = readdir($handle))) {
              if ($file != "." && $file != "..") {
                  echo "<a href='".$dos.$file."'>$file</a>\n";
              }
          }
          closedir($handle);
      }

	  ?>
Je ne demande pas qu'on m'envoie chier, ni d'aller regarder sur le net, les anciens me connaissent, je cherche juste à gagner un peu de temps car ce script est à ma portée...mais comme beaucoup je dois gérer 36 000 trucs à la fois.

Merci à vous, à toi Ryle et à la PHPfrance team :)

Mega
;)

Posté : 26 mars 2009, 04:26
par Nagol
la réponse est fonction récursive, comme je suis de bonne humeur et que je m'ennuie, voilou
<?php

function scanrec($dir='root', $debug=false) {
    $result = array();
    if($dir == 'root') {
        $dir = dirname(__FILE__);
    }
    $dir = trim($dir);
    if(DIRECTORY_SEPARATOR == '/') {
        $dir = str_replace('\\', DIRECTORY_SEPARATOR, $dir);
    } else {
        $dir = str_replace('/', DIRECTORY_SEPARATOR, $dir);
    }
    $dir = str_replace(DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, $dir);
    if($debug) {
        echo 'Requested: "' . $dir . '"'."\n";
    }
    $dir = realpath($dir);
    if(is_dir($dir)) {
        if($dir[strlen($dir - 1)] != DIRECTORY_SEPARATOR) {
            $dir .= DIRECTORY_SEPARATOR;
        }
        if($debug) {
            echo 'Scanning: "' . $dir . '"' . "\n";
        }
        $curlist = glob($dir . '*');
        for($i=0; $i<count($curlist); $i++) {
            array_push($result, $curlist[$i]);
            if(is_dir($curlist[$i])) {
                $curcontent = scanrec($curlist[$i], $debug);
                for($j=0; $j<count($curcontent); $j++) {
                    array_push($result, $curcontent[$j]);
                }
            }
        }
    }
    return $result;
}

echo '<pre>';
print_r(scanrec('\\\\home\\\\logan                   ', true));
echo '</pre>';


Posté : 26 mars 2009, 06:00
par Nagol
Bah j'ai relu, et ensuite je me suis dit que j'avais pas compris la question ceci dit tu pourrais utiliser mon premier script et faire un truc en javascript tout mignon, dans le cas contraire tu pourrais utiliser ça:

<?php

function listcurdir($root='root', $dir='root', $debug=false) {
    $result = array();
    if($dir == 'root' || is_null($dir)) {
        if($root != 'root') {
            $dir = $root;
        } else {
            $dir = dirname(__FILE__);
        }
    } else {
        $dir = base64_decode(urldecode($dir));
    }
    if($root == 'root' || is_null($root)) {
        $root = dirname(__FILE__);
    }
    if(!preg_match('`^'.$root.'`', $dir)) {
        if($debug) {
            echo 'Error: ' . $dir . ' isnt in '. $root . '!' . "\n";
        }
        return $result;
    }
    $dir = trim($dir);
    $root = trim($root);
    if(DIRECTORY_SEPARATOR == '/') {
        $dir = str_replace('\\', DIRECTORY_SEPARATOR, $dir);
        $root = str_replace('\\', DIRECTORY_SEPARATOR, $root);
    } else {
        $dir = str_replace('/', DIRECTORY_SEPARATOR, $dir);
        $root = str_replace('/', DIRECTORY_SEPARATOR, $root);
    }
    $dir = str_replace(DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, $dir);
    $root = str_replace(DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, $root);
    if($debug) {
        echo 'Requested: "' . $dir . '"'."\n";
    }
    $dir = realpath($dir);
    $root = realpath($root);
    $tmp = explode(DIRECTORY_SEPARATOR, $dir);
    array_pop($tmp);
    $prevdir = implode(DIRECTORY_SEPARATOR, $tmp);
    if($dir[strlen($dir - 1)] != DIRECTORY_SEPARATOR) {
        $dir .= DIRECTORY_SEPARATOR;
    }
    if($root[strlen($root - 1)] != DIRECTORY_SEPARATOR) {
        $root .= DIRECTORY_SEPARATOR;
    }
    if($prevdir[strlen($prevdir - 1)] != DIRECTORY_SEPARATOR) {
        $prevdir .= DIRECTORY_SEPARATOR;
    }
    if($debug) {
        echo 'Scanning: "' . $dir . '"' . "\n";
    }
    if($root == $prevdir || preg_match('`^'.$root.'`', $prevdir)) {
        array_push($result, array('link'=>urlencode(base64_encode($prevdir)), 'type'=>'D', 'name'=>'..'));
    }
    $curlist = glob($dir . '*');
    for($i=0; $i<count($curlist); $i++) {
        $type = 'U';
        if(is_dir($curlist[$i])) {$type = 'D';}
        if(is_file($curlist[$i])) {$type = 'F';}
        if(is_link($curlist[$i])) {$type = 'L';}
        array_push($result, array('link'=>urlencode(base64_encode($curlist[$i])), 'type'=>$type, 'name'=>str_replace($dir, '', $curlist[$i])));
    }
    return $result;
}

if(isset($_GET['dir'])) {
    $dir = $_GET['dir'];
} else {
    $dir = null;
}

$list = listcurdir('/home/logan', $dir);

function cmp($a, $b){
    if($b['name'] == '..') return +1;
    if ($a['type'] == $b['type']) {
        if(strtolower($a['name']) == strtolower($b['name'])) {
            return 0;
        } else {
            return (strtolower($a['name']) > strtolower($b['name'])) ? +1 : -1;
        }
    }
    return ($a['type']=='D' && ($b['type'] == 'F' || $b['type'] == 'L')) ? -1 : +1;
}

usort($list, "cmp");

echo '<ul>' . "\n";
foreach($list as $file) {
    if($file['type'] == 'D') {
        $text = '<a href="'.$_SERVER['PHP_SELF'].'?dir=' . $file['link'] . '">'.$file['name'].'</a>';
    } else {
        $text = $file['name'];
    }
    echo '<li>('.$file['type'].')&nbsp;' . $text . '</li>' . "\n";
}
echo '</ul>' . "\n";



Posté : 26 mars 2009, 06:12
par Nagol
Donc pour commenter un peu les principaux points sont:

-les données passées en url doivent être protégée (urlencode base64_encode)
-la fonction te renvoit pour chaque fichier un array contenant le type (Dossier, Fichier, Link)
-Les résultats sont ordonnés classiquement (répertoire d'abord, fichiers ensuite, chacun ordonnés alphabétiquement et case insensitivement les uns par rapport aux autres)
-l'appel de fonction comprend un root et un dir, le root c'est le répertoire le plus haut qu'on peut browser, le dir c'est le répertoire de départ, ca devrait être assez souple pour que tu puisse faire un peu ce que tu veux
-pour chaque résultat, le premier fichier est le répertoire parent (sauf si on est dans le root) on peut s'amuser à taper l'argument nécessaire pour browser au dessus du root mais la fonction va pondre un tableau vide, à toi de faire la gestion d'erreur qui te convient
-les balises utilisées sont des ul, li, c'est assez facile à customizer pour faire ressembler le tout à un vrai répertoire

Voilou, en tout cas tu m'as occupé dans mon insomnie :)

Posté : 26 mars 2009, 14:36
par Megadeth
Salut, content d'avoir pu te rendre service lol

En tout cas un grand MERCI Nagol, je pense que tu m'as fait gagné quelques précieuses heures.

Musicalement,

Mega
;)

Posté : 28 mars 2009, 18:21
par Nagol
y'a pas de quoi

oublie pas le résolu si c'est résolu :)

Posté : 29 mars 2009, 14:53
par Megadeth
Exact, j'avais bidouillé un script de mon côté qui obligeait à mettre un fichier index différent à chaque "sous-étage", moins pratique que le tien mais très fonctionnel :)