Bonjour je cherche à enregistrer un répertoire dans un array(); mon code:

$dir = "app/galleries/";
    $rep = array();
    if (is_dir($dir)) {
        if ($dh = opendir($dir)) {
            while (($file = readdir($dh)) !== false) {
                if($file != "." && $file != ".."){

                    $rep] = array(
                        $file => array(
                            "nom de la gallerie" => "liste des images"
                        )
                    );
                }
            }
            closedir($dh);
        }
    }

Le dossier galleries est organisé ainsi:

Gallerie
    |
    |- Flickr
        |
        |- gallerie 1
                |
                |- thunbs
                |- image 1
                |- image 2
                |- image 3
                |

La ou je coince c'est pour bouclé au niveau des images.

27 réponses


Xtr3me
Réponse acceptée

La mise en forme de ton tableau est impossible.
Ma fonction fonctionne très bien mis à part qu'il faut chercher dans un dossier précis les fichiers contenus donc soit tu la modifies pour qu'elle corresponde à ce que tu souhaites soit tu utilises la classe DirectoryIterator.
Sinon j'avais demandé sur le Site du Zéro de l'aide pour ma fonction au lieu de m'aider on m'a proposé une fonction faites avec DirectoryIterator la voici:

function tree(DirectoryIterator $dir)
{
    $tree = array();

    foreach ($dir as $node) {
        /** @var DirectoryIterator $node */

        if ($node->isFile()) {
            $tree] = $node->getFilename();
        }

        if ($node->isDir() && !$node->isDot()) {
            $tree$node->getFilename()] = tree(new DirectoryIterator($node->getPathname()));
        }
    }

    return $tree;
}

var_dump(tree(new DirectoryIterator('.')));

Je l'ai essayé elle fonctionne très bien et te conviendra puisque ma fonction ne fait pas vraiment la même chose elle la mienne s'occupe de reconstruire l'arborence des fichiers ayant l'extension JPG dans le dossier spécifié.
Celle-ci va naviguer à travers tout les dossiers pour te donner un tableau contenant les dossiers et les fichiers tu peux lui spécififier à partir de quel endroit tu veux quelle commence.

Tu veux récupérer chaque image c'est ça ? La fonction glob va t'intéressait dans ce cas ;) .
Je te laisse faire un tour sur la doc php avec la fonction glob tu pourras repérer les images par leur extensions et récupérer le tout sous la forme d'un tableau.

vavoir
Auteur

Je ne veux pas récupérer que les images mais aussi le nom du répertoire qui leur est associé. Je vais faire un tour sur la doc et je bidouille tout sa.

Tu peux utiliser la fonction dirname qui te renvoie le dossier parent dans ce cas ;) tu utilises glob pour récupérer les images et tu fais un dirname pour connaître le dossier parents et tu tries ça dans un tableau. Enfin c'est comme ça que je ferai.
Tu peux toujours faire une boucle pour le dirname qui va jusqu'à $dir == "Galerie"; par exemple.

vavoir
Auteur

Je comprend pas comment fonctionne glob j'ai mis ce code:

foreach (glob('app/galleries/') as $filename) {
        echo "$filename occupe " . filesize($filename) . "\n";
        var_dump($filename);
    }

Et il m'affiche "app/galleries/ occupe 4096" quand a var_dump il me renvoie

string 'app/galleries/' (length=14)

La fonction glob comme indiqué sur la doc officielle fonctionne avec un motif à retrouver parmi les fichiers donc tu dois spécifier une chaîne qui permettra d'identifier les images ;) .

foreach (glob("*.jpg") as $filename) {
        echo "$filename occupe " . filesize($filename) . "\n";
        var_dump($filename);
    }

Par exemple la fonction glob va te trouver tout les fichiers .JPG donc $filename correspondra au nom du fichier en l'occurrence les images.

Ensuite tu fais une boucle du genre:

while($dir != "Galerie"){
$dir = dirname($dir);
}

Je te donne pas la solution complète il faut chercher aussi en gros la boucle continuera jusqu'à ce que $dir soit égal à "Galerie" tu rajoutes à chaque fois $dir dans ton tableau ;) puisque tu vas remonter tout les dossiers jusqu'à arriver au dossier Galerie. Tu vas avoir toute l'arborescence pour chaque fichier. A toi d'adapter à ton code je te donne juste les pistes n'ayant pas suffisamment de code pour tester et puis n'ayant pas le temps de tester moi même.

vavoir
Auteur

En gros on doit avoir un truc dans ce genre reste juste à le faire marcher.

<?php
    function Galleries($dir){
        $imgs = array();
        if (is_dir($dir)) {
            if ($dh = opendir($dir)) {
                while (($file = readdir($dh)) !== false) {
                    if($file != "." && $file != ".." ){
                        if(filetype($dir.$file) == dir){
                            $nomdurepertoire = $file;
                        }
                        foreach (glob($dir.$file."/*.jpg") as $filename) {
                            if(filetype($dir.$file) == dir){
                                $nomdelagallerie = $file;
                            }
                           $imgs] = array(
                                $nomdurepertoire => array(
                                    $nomdelagallerie = array($filename)
                                )
                            );
                        }
                    }
                }
                $file = readdir($dh);              
                closedir($dh);
            }
        }
        return $imgs;
    }
    var_dump(Galleries('app/galleries/'));

Galerie et non Gallerie ;) .
Si je ne dis pas de bêtise il n'y a pas besoin de spécifier le chemin dans la fonction glob.

foreach (glob($dir."*.jpg") as $filename) {

                            if(filetype($dir.$file) == dir){
                                $nomdelagalerie = $file;
                            }

                           $imgs$nomdelagalerie] = $filename;
                        }
while($dir != "Galerie"){
$rep] = $dir;
$dir = dirname($dir);
}

Je te mets sur la voie normalement là tu vas récupérer les répertoires/dossiers dans le tableau $rep et le nom du fichier avec le nomdelagalerie dans le tableau $imgs.

vavoir
Auteur

Non il met

Notice: Undefined variable: filename in A:\wamp\www\***.php on line 21

<?php
    function Galleries($dir){
        $imgs = array();
        if (is_dir($dir)) {
            if ($dh = opendir($dir)) {
                while (($file = readdir($dh)) !== false) {
                    if($file != "." && $file != ".." ){
                        foreach (glob("*.jpg") as $filename) {

                            if(filetype($dir.$file) == dir){
                                $nomdelagalerie = $file;
                            }

                           $imgs$nomdelagalerie] = $filename;
                        }
                        while($dir != "galleries"){
                            $rep] = $dir;
                            $dir = dirname($filename);
                        }
                    }
                }
                $file = readdir($dh);              
                closedir($dh);
            }
        }
        return $imgs;
    }
    var_dump(Galleries('app/galleries/'));

et effectivement la variable filename et définie dans le foreach mais bon on va bien finir pas y arriver ^^

Tu as pas mis la boucle dans le foreach donc la variable $filename n'est pas définis j'ai essayé de faire quelque chose mais ça en devient d'une complexité Oo . J'arrive pas en fait à faire un array multidimensionnel récursif avec pour chaque clé le nom du dossier je suis en pleine étude du cas là .

vavoir
Auteur

Oui c'est effectivement le plus dur comment associer chaque image a sa galerie et chaque galeries a son dossier du coup on obligé de mettre plusieurs tableau les un dans les autre bon sa c'est pas très dur le plus dur et de les remplir aaah les joies de la récursivité mais tiens ou ce foutu tuto déjà ou j'ai rein compris...

En fait c'est surtout que j'ai récupéré tout le répertoire dans un tableau donc ça fonctionne mais j'aurai faire comme une arborescence et ça je vois pas pour le moment comment faire.
C'est à dire en quelques sortes empiler les index.
Tu aurais donc comme premier index la racine puis sa valeur serait un tableau avec index le sous-dossier et ainsi de suite.

Le plus simple actuellement c'est de réutiliser le tableau étant donné que tout les dossiers sont dans l'ordre (racine à l'image) tu peux simplement reconstituer l'arborescence en comptant le nombre d'index et en appelant celui voulu.

Edit: j'ai réussi à le faire sur 2 niveaux je continue ça pourrait me servir.

Bon j'ai abandonné c'est vraiment la galère de trier le tableau de façon multidimensionnel.
Donc en gros je te montre ce que tu faire:

function Galleries($dir){

        $imgs = array();

        if (is_dir($dir)) {
            if ($dh = opendir($dir)) {
                while (($file = readdir($dh)) !== false) {
                    if($file != "." && $file != ".." ){

                        foreach (glob($dir."*.jpg") as $filename) {

                            if(filetype($dir.$file) == dir){
                                $nomdelagalerie = $file;
                            }

                           $imgs$nomdelagalerie] = $filename;
                           $folders = explode("/",$filename);
                        }

                    }
                }
                $file = readdir($dh);             
                closedir($dh);
            }
        }

        return $imgs;

    }

Le tableau $folders sera un tableau contenant toute l'arborescence de ton fichier j'ai pas trouvé d'autres moyens de le faire...
J'ai essayé avec les fonctions array_search,unset,each,next etc... pas réussi à tout coordonner pour faire ce que je voulais j'ai réussi à le faire sur 2 niveaux en fait donc inutile...

J'ai essayé de faire de la récursivité c'est vraiment galère en fait mon idée c'était de faire un tableau avec comme premier indice la racine et pour valeur un array vide il aurait fallu vérifier que cette soit vide ou non si oui tu lui rajoutes le second éléments du tableau $folders et ainsi de suite.
Je dois pas avoir les idées assez clair apparemment ;) .

Edit:

Au cas où ça t'intéresserai voilà où j'en étais:

function arbor($dir){
        foreach(glob($dir."*.jpg") as $path){
          $folders = explode("\\",$path);
          $count = count($folders);
          $i=0;
        }
        $rep[0] = array($folders[0] => null);
        $pos = pos($rep);
        if(!isset($folder)){
            $folder = $folders[0];
          }
        $tr = getdir($folders,$folder,$pos);
     }
     function getdir($folders,$folder,$pos){          
            if(empty($pos$folder])){
              $search = array_search($folder, $folders);
              unset($folders$search]);
              $pos$folder] = array($folder => null);
              if(!empty($folders)){
                $folder = pos($folders);
                getdir($folders,$folder,$pos);
              }
          }
          return $pos;
     }
     arbor($dir);

T'occupes pas des noms des fonctions etc... ils sont totalement arbitraires il faudrait en gros rendre le traitement fait par getdir récursive là pour le moment ça fait que 2 niveau de l'arborescence.
Je suis certain qu'avec de la persévérance et un peu de jugeote tu pourras en tirer quelque chose. Là je me heurte à ce problème pour rien.

J'ai pris 20 minutes de mon temps aujourd'hui en gardant l'esprit et les idées claires et figure-toi que j'ai réussi ;) .

function arbor($dir){
        foreach(glob($dir."*.jpg") as $path){
          $folders = explode("\\",$path);
          $count = count($folders)-1;
          $i=0;
        }
        for($i=0; $i<$count;$i++){
          $folders$i] = array($folders$i] => null);
        }
        end($folders);
        $start = $folders[0];
        $tr = getdir($folders,false,$start);
        return $tr;
     }
     function getdir(&$folders,$prev = false,$start = false){
              if($prev != $start){    
                $prev = prev($folders);
                $search = array_search($prev, $folders);
                $next = $search + 1;
                  foreach($folders$search] as $k => $v){
                      $folders$search]$k] = $folders$next];  
                  }
                getdir($folders,$prev);
                unset($folders$next]);
              }
              return $folders;
     }
     arbor($dir);

Le tout te renverra un tableau multidimensionnel en mode poupée russe en partant de la racine et allant jusqu'au fichier.
Sinon tu peux le faire avec la classe DirectoryIterator mais je tenais à faire ma propre fonction.

vavoir
Auteur

On doit pas avoir la même arborescence.

Warning: Invalid argument supplied for foreach() in A:\wamp\www\the-world-of-childhood.ru\app\models\home.php on line 21

le code:

function arbor($dir){
        foreach(glob($dir."*.jpg") as $path){
          $folders = explode("\\",$path);
          $count = count($folders)-1;
          $i=0;
        }
        for($i=0; $i<$count;$i++){
          $folders$i] = array($folders$i] => null);
        }
        end($folders);
        $start = $folders[0];
        $tr = getdir($folders,false,$start);
        return $tr;
     }
     function getdir(&$folders,$prev = false,$start = false){
              if($prev != $start){    
                $prev = prev($folders);
                $search = array_search($prev, $folders);
                $next = $search + 1;
                  foreach($folders$search] as $k => $v){
                      $folders$search]$k] = $folders$next];  
                  }
                getdir($folders,$prev);
                unset($folders$next]);
              }
              return $folders;
     }
    // arbor($dir);
var_dump(arbor('app/galeries/'));

dump:

array (size=1)
  0 => string 'app/galeries/22947190Fxn.jpg' (length=28)

Mon arborescence:

app
    |
    |- control
    | |
    | |- mon fichier php qui appel le model et la vue
    |
    |- model
    | |
    | |- mon model qui contient ta fonction
    |
    |- vue
    | |
    | |- ma vue
    |
    |-Gallerie
        |
        |- Flickr
            |
            |- gallerie 1
                    |
                    |- thunbs
                    |- image 1
                    |- image 2
                    |- image 3
                    |

Il faut mettre un chemin valide qui contient des images .JPG bon le code peut être modifié pour demander l'extension par exemple et là il récupère que le dernier fichier étant donnée que j'appelle ma fonction getdir en dehors de la boucle foreach ;) .
Tu mets comme dossier 'app/galeries' mais dans ton arborescence je vois app et pas galeries juste Gallerie,gallerie.
Je te conseille de faire ça pour vérifier que tu ne te trompes pas.

if(file_exists('app/galeries/22947190Fxn.jpg')){
       echo "Le fichier existe";
}else{
       echo "Le fichier n'existe pas";
}

Si ça te retourne le fichier existe alors tu supprimes le nom du fichier et tu le mets en argument de la fonction sinon c'est que tu t'es trompé.
Si ça ne marche toujours pas il faut voir du côté des slash si tu regardes bien dans la fonction je fais un explode par les "\" et non par "/". Etant donnée que mes chemins sont composés uniquement d'antislash alors que les tiens sont des slash voilà la différence ^^ .

Voilà comment est définis un de mes chemins:
E:\Sites\Kinapa\webroot\img\products\chaussures\ballerines\104\

Essayes ainsi et dis-moi ce que tu as ;) .

vavoir
Auteur

Le fichier existe, quand a savoir si le dossier et vide j'ai fait clic droit propriété et il m'affiche:

contenu: 5 281 Fichiers, 229 Dossiers

ATTENTION !
Le dossier "Galeries" ne contient que des dossiers. Les images ce trouve plus en profondeur dans les sous-dossier voir arborescence:

app
 |
 |- control
 | |
 | |- mon fichier php qui appel le model et la vue
 |
 |- model
 | |
 | |- mon model qui contient ta fonction
 |
 |- vue
 | |
 | |- ma vue
 |
 |-Gallerie
     |
     |- Flickr
         |
         |- gallerie 1
                 |
                 |- thunbs
                 |- image 1
                 |- image 2
                 |- image 3
                 |

Essayes en mettant des antislashs dans ce cas j'ai essayé et j'ai aucun soucis personnellement ou tu changes la fonction pour qu'elle fonctionne avec des slashs (il suffit de remplacer "\" par "/" dans l'explode).

P.S: Dans ton arborescence que tu nous présentes les chemins sont différents que ceux que tu nous donnes lequel dit vrai ?
Et on écrit miniature: Thumbs pas Thunbs ^^ .

Quand je dis si le fichier existe je te parle pour ton script PHP pas pour toi je me doute bien que le fichier existe mais faut-il encore que PHP le détecte ;) .

vavoir
Auteur

Y du mieux mais c'est pas core sa ^^

code

<?php
    function arbor($dir){
        foreach(glob($dir."*.jpg") as $path){
          $folders = explode("/",$path);
          $count = count($folders)-1;
          $i=0;
        }
        for($i=0; $i<$count;$i++){
          $folders$i] = array($folders$i] => null);
        }
        end($folders);
        $start = $folders[0];
        $tr = getdir($folders,false,$start);
        return $tr;
     }
     function getdir(&$folders,$prev = false,$start = false){
              if($prev != $start){    
                $prev = prev($folders);
                $search = array_search($prev, $folders);
                $next = $search + 1;
                  foreach($folders$search] as $k => $v){
                      $folders$search]$k] = $folders$next];  
                  }
                getdir($folders,$prev);
                unset($folders$next]);
              }
              return $folders;
     }
    // arbor($dir);

var_dump(arbor('app/galeries/'));

array (size=1)
  0 => 
    array (size=1)
      'app' => 
        array (size=1)
          'galeries' => string '22947190Fxn.jpg' (length=15)

EDIT:

Je me suis demander ce qui se passerait si je retirais l'image qu'il détecte et j'obtient deux erreur:

Notice: Undefined variable: count in A:\wamp\www\***\app\models\home.php on line 8
     Warning: end() expects parameter 1 to be array, null given in A:\wamp\www\***\app\models\home.php on line 11

Oui c'est exactement ce genre de tableau que j'obtiens avec la fonction ;) .
Si tu regardes bien count c'est un comptage du nombre d'éléments du tableau $folders -1 car on commence à 0 le soucis c'est qu'en enlevant le nom de l'image la fonction glob ne trouve rien apparemment donc le tableau $folders n'existe pas du coup c'est un objet de type null qui est dans la fonction end.

J'ai pas géré tout les cas d'erreurs j'ai voulu faire au plus simple faut voir comment tu peux manipuler la fonction glob.
Comme je l'ai dit elle récupère que le dernier fichier la fonction tu dois pouvoir en déplaçant tout ce qui est en dehors du foreach de la fonction arbor dans la fonction foreach, récupérer chaque tableau cependant comme les dossiers seront les mêmes il faut voir quel comportement tu auras.

Tu pourrais très bien vérifier dans le foreach de arbor si le dernier index est !empty alors tu crées un tableau avec les différents non-associatif avec chaque fichier ^^ . Si tu veux je regarderai ça demain ;) .

vavoir
Auteur

Ok mais ce que je comprend pas c'est pourquoi il n'arrive pas à recuperer les dossiers car avec la fonction opendir j'arrivais bien à récupérer tout les nom des dossiers il ne rester plus qu'a stoker se nom dans le array puis d'ouvrir le dossier. La tout ce que j'ai pu comprendre de la fonction c'est quelle cherche des .jpg dans le dossier "galeries" hors il n'y en AUCUN car c'est .jpg se trouve plus en profondeur dans les sous-dossier. Une chose que l'on sait c'est que les images ce trouve TOUJOURS dans le troisième sous-repertoir en partant de galerie donc je pense que lorsque qu'on ait a ce niveau il faut alors chercher les .jpg et les lister dans un array.

La fonction te permet de regarder dans le dossier définis par toi même tout les fichiers contenant des .JPG elle est très basique je t'ai dit on pourrait très bien passer en argument l'extension recherché et modifié par conséquent le .JPG par l'argument.
Admettons que tes images soient dans "app/galeries/flickr/galerie" d'abord si tu écris le dossier de cette manière il faudra modifier la fonction pour qu'elle explose par les / et non pas les \ comme c'est le cas actuellement.

Ensuite elle te retournera tout les fichiers au format .JPG contenu dans le dossier galerie qui lui est contenu dans flickr qui lui est contenu dans galeries qui à son tour est dans app.
Enfin tout les fichiers oui c'est ce que fait la fonction glob mais actuellement la fonction que j'ai codée ne le fait qu'avec le dernier fichier il suffit juste de la modifier un peu mais le principe est là ;) .

vavoir
Auteur

D'accord donc pour l'instant elle ne s'occupe pas des répertoires. Donc en gros il faudrait faire un truc du genre:

$dir = "/tmp/php5";
// Ouvre un dossier bien connu, et liste tous les fichiers
if (is_dir($dir)) {
    if ($dh = opendir($dir)) {
        while (($file = readdir($dh)) !== false) {
            ici la function
        }
        closedir($dh);
    }
}

Comment ça elle ne s'occupe pas des répertoires ?
Peux-tu m'expliquer clairement ce que tu veux et sous quelle forme tu le veux ?

vavoir
Auteur
Votre code ici...

Un tableau de ce genre:

PHP

$truc = array(
        "galerie" => array(
            "flick" => array(
                "gallerie1" => array(
                    "image1.jpg",
                    "image2.jpg",
                    "image3.jpg",
                    "etc...",
                )
            ),
            "picassa"   => array(
                "gallerie1" => array(
                    "image1.jpg",
                    "image2.jpg",
                    "image3.jpg",
                    "etc...",
                )
            ),
        )
    );
vavoir
Auteur

merci de cette function il ne me restera plus qu'a afficher les info d'on j’aurais besoin en tout cas c'est exactement ce que je voulais d’ailleurs je m'attendais a plus de code pour faire sa ^^

La classe DirectoryIterator est directement implanté dans PHP elle contient des fonctions faites pour ce genre d'opération tu trouves qu'il n'y a pas beaucoup de codes parce que tu ne vois pas les fonctions de la classe ;) . Si tu avais eu à faire la même chose tout seule là tu aurais été étonné de voir autant de code ;D .
Je retourne sur mon projet si ton problème est résolu ^^ .