login  Naam:   Wachtwoord: 
Registreer je!
 Forum

Probleem lezen dirs/images met php (Opgelost)

Offline Martijn2008 - 12/07/2009 16:43
Avatar van Martijn2008PHP beginner Hallo Sitemasters,

Ik heb een klein probleempje met het lezen van dirs en files met PHP. 9 van de 10 keer gaat het goed, maar die ene keer niet. Voor Firefox gebruikers is dat niet zo'n drama, maar voor IE gebruikers wel. De hele site layout wordt namelijk uit elkaar getrokken.

Het is de bedoeling dat alle album dirs worden ingelezen en in een array worden geplaatst. Vervolgens wordt er random een album uitgekozen en de images in deze dir ingelezen in een array. Uit al deze images worden random 4 images gekozen. Nu wil het zo nu en dan wel is voorkomen dat er een lege string met images gereturned wordt. Dat zijn dan bijvoorbeeld 1 of 2 van de 4 afbeeldingen. Dit zorgt ervoor dat mijn layout uit elkaar getrokken wordt in IE.

De code vind je hier.

Hebben jullie misschien een idee?

Martijn

12 antwoorden

Gesponsorde links
Offline Ibrahim - 12/07/2009 16:57 (laatste wijziging 12/07/2009 16:59)
Avatar van Ibrahim PHP expert Ik zou de functie PHP.net: scandir en de functie PHP.net: array_rand en de functie PHP.net: file_exists eens bekijken. Je kunt je code tot wel 4x zo klein maken.

Allereerst lees je met behulp van scandir je fotoalbum map uit. Die geeft je een Array terug met alle album mappen. Per map gebruik je weer scandir. Alle gegevens sla je dan in een multi-dimensionale Array op. Ik dacht aan zo'n vorm:

  1. $myPhotoAlbums = array('Album 1' => array('Photo 1' => 'filename.ext', 'Photo 2' => 'filename.ext'), 'Album 2' => array(...));


Met deze Array kun je array_rand toepassen om zo random een album te selecteren:

  1. $currentAlbumIdentifier = array_rand($myPhotoAlbums);


Nu je $currentAlbumIdentifier hebt, kun je de juiste afbeeldingen selecteren. Om je layout niet te verpesten kun je controleren of er vier afbeeldingen zijn in je array. Als dit niet het geval is, kun je twee dingen doen:

- dit alles via een recursieve functie schrijven zodat je bij een gebrek aan 4 afbeeldingen een nieuwe album geselecteerd word
- de ontbrekende afbeeldingen opvullen met een "no-photo-available" afbeelding

Ik hoop dat je genoeg info hebt om verder te kunnen.

edit: je selecteert je album dan natuurlijk op deze manier:

  1. $currentAlbumIdentifier = array_rand($myPhotoAlbums);
  2. $currentAlbum = $myPhotoAlbums[$currentAlbumIdentifier];
Offline Martijn2008 - 12/07/2009 17:13 (laatste wijziging 12/07/2009 23:34)
Avatar van Martijn2008 PHP beginner Bedankt voor de alle informatie Ibrahim. Ik zal even kijken in hoeverre me dit gaat lukken want het klinkt nogal ingewikkeld. Zodra ik weer nieuws te melden heb breng ik jullie op de hoogte 

UPDATE: Ik weet eigenlijk niet goed hoe ik moet beginnen.
Offline Ibrahim - 13/07/2009 00:34
Avatar van Ibrahim PHP expert Je hebt een hoofdmap met albums. Elke album is een submap van deze hoofdmap. Je moet dus de hoofdmap uitlezen met PHP.net: scandir. Van scandir krijg je een array met de submappen van deze hoofdmap terug. Probeer het maar uit:

  1. $myPhotoAlbums = scandir($photoAlbumsPath);
  2. echo '<pre>' , var_dump($myPhotoAlbums) , '</pre>';


Uit deze resultaten zie je dat naast je submappen ook de entries "." en ".." terugkrijgt. Bij het loopen door deze array met PHP.net: foreach moet je deze dus negeren/uit de array halen.

Dus nu heb je een array met alle albums (submappen van de hoofdmap). Elke Array entry is een album. Dit betekent dat elke entry afbeeldingen bevatten. Dus moet je per entry weer PHP.net: scandir toepassen:

  1. $photoAlbums = array();
  2. foreach ($myPhotoAlbums as $albumName) {
  3.  
  4. $photoAlbums[$albumName] = scandir($photoAlbumsPath . '/' . $albumName);
  5. }


Nu heb je de array gemaakt die ik in me eerste reactie voorstelde. Aangezien je van scandir alweer de "." en ".." terugkrijgt, moet je ook hier die filtereren.

Hoop dat je nu wel verder kan. Probeer het minstens 3 dagen voor je weer hier om hulp gaat vragen. zo dwing je jezelf om beter te worden.
Offline Martijn2008 - 13/07/2009 11:13 (laatste wijziging 14/07/2009 22:55)
Avatar van Martijn2008 PHP beginner Het is me gelukt om de multidimensionale array te fixen. Nu heb ik een volgend probleem: ik weet niet hoe ik de array binnen de array moet bewerken. Ik moet namelijk de albumnaam en de foto's ophalen uit de array. De array ziet er nu zo uit:

  1. array(0) {
  2. ["Album 1"]=>
  3. array(2) {
  4. [0]=>
  5. string(12) "DSC0001.JPG"
  6. [1]=>
  7. string(12) "DSC0002.JPG"
  8. [2]=>
  9. string(12) "DSC0003.JPG"
  10. }
  11. }


Mijn php-code ziet er nu als volgt uit:

  1. <?php
  2.  
  3. function getDirectoryTree( $outerDir )
  4. {
  5. $dirs = array_diff( scandir( $outerDir ), Array( ".", ".." ) );
  6. $dir_array = Array();
  7. foreach( $dirs as $d )
  8. {
  9. if( is_dir($outerDir."/".$d) )
  10. {
  11. $dir_array[ $d ] = getDirectoryTree( $outerDir."/".$d );
  12. }
  13. else
  14. {
  15. $dir_array[] = $d;
  16. }
  17. }
  18. return $dir_array;
  19. }
  20.  
  21. $dirList = getDirectoryTree('.');
  22. $countDirs = count($dirList);
  23. $randomDir = rand(0, $countDirs);
  24. $album = $dirList[$randomDir];
  25.  
  26. $countPhotos = count($album);
  27.  
  28. // Haal 4 random photos op
  29. for($i = 0; $i < 4; $i++)
  30. {
  31. $randomPhoto = rand(0, $countPhotos);
  32.  
  33. echo ($file = $album[$randomDir][$randomPhoto]) . "<br />\n";
  34. }
  35.  
  36. echo '<pre>' , var_dump( $dirList ) , '</pre>';
  37.  
  38. ?>
Offline snxs - 21/07/2009 20:37 (laatste wijziging 21/07/2009 20:45)
Avatar van snxs Nieuw lid Je maakt één fout, die zag ik in je eerdere code ook al.
  1. echo ($file = $album[$randomDir][$randomPhoto]) . "<br />\n";


Dit hoort anders, en wel:
  1. $file = $album[$randomDir][$randomPhoto];
  2. echo $file . "<br />\n";


Ook sluit je daar je echo al af met de ")". Dus zou je een php error krijgen. Het getten van je data uit je array doe je wel goed. Voor ieder niveau binnen een multi dimensionale array kun je weer "[]" gebruiken.
  1. $multi_array = array(
  2. "level1_rij1" => array(
  3. "level2_rij1" = array(
  4. "level3_rij1" => "je eerste waarde",
  5. "level3_rij2" => "je tweede waarde"
  6. ),
  7. "level2_rij2" = array(
  8. "level3_rij1" => "je derde waarde",
  9. "level3_rij2" => "je vierde waarde"
  10. ),
  11. "level2_rij3" = array(
  12. "level3_rij1" => "je vijfde waarde",
  13. "level3_rij2" => "je zesde waarde"
  14. )
  15. ),
  16. "level1_rij2" => array(
  17. "level2_rij1" = array(
  18. "level3_rij1" => "je zevendewaarde",
  19. "level3_rij2" => "je achtste waarde"
  20. ),
  21. "level2_rij2" = array(
  22. "level3_rij1" => "je negende waarde",
  23. "level3_rij2" => "je tiende waarde"
  24. ),
  25. "level2_rij3" = array(
  26. "level3_rij1" => "je elfde waarde",
  27. "level3_rij2" => "je twaalfde waarde"
  28. )
  29. )
  30. );
  31.  
  32. //zo resulteert onderstaande code in: "je elfde waarde".
  33. echo $multi_array["level1_rij2"]["level2_rij3"]["level3_rij1"];


Ik hoop dat ik het een beetje simpel gehouden heb... ;)


En bij jou is je album naam dus:
  1. $randomDir

En je foto naam:
  1. $randomPhoto


Nu heb je alleen één probleem: je kan meerdere keren dezelfde foto ophalen, de kans hier op hangt van de hoeveelheid foto's in je album af.

Je zou eventueel eerst een array van 4 getallen kunnen genereren die binnen het aantal foto's van je album valt maar nooit het zelfde getal 2 keer heeft.

En dan in de for die getallen pakken:
  1. $photo_array[$i]
Offline Martijn2008 - 21/07/2009 21:30 (laatste wijziging 21/07/2009 21:42)
Avatar van Martijn2008 PHP beginner Het gaat mis bij de directory's (albums). Ik weet niet hoe ik daar random een album moet kiezen. Wanneer ik nou een dir wil kiezen, moet ik een count uitvoeren op de buitenste array, maar ik weet dan niet hoe ik de binnenste array moet selecteren. Doordat count een nummerieke waarde teruggeeft en de buitenste array de dirName draagt. En geen nummerieke waarde

Van de echo heb ik overigens geen last. Dit werkt gewoon zonder php foutmeldingen.
Offline snxs - 21/07/2009 22:51
Avatar van snxs Nieuw lid Vervang:
  1. $dirList = getDirectoryTree('.');
  2. $countDirs = count($dirList);
  3. $randomDir = rand(0, $countDirs);
  4. $album = $dirList[$randomDir];
  5.  
  6. $countPhotos = count($album);


Voor:
  1. $dirList = getDirectoryTree('.');
  2. $album = array_rand($dirList);
  3.  
  4. $countPhotos = count($album);
Offline Martijn2008 - 22/07/2009 00:06 (laatste wijziging 22/07/2009 00:21)
Avatar van Martijn2008 PHP beginner Ik heb mijn code aangepast. Het werkt nu slechts gedeeltelijk. Af en toe worden er helemaal geen foto's weergeven. En... soms worden er slechts 2 van de 4 foto's opgehaald. De variabele $file blijft in dat geval leeg.

  1. <?php
  2.  
  3. function getDirectoryTree( $outerDir )
  4. {
  5. $dirs = array_diff( scandir( $outerDir ), Array( ".", ".." ) );
  6. $dir_array = Array();
  7. foreach( $dirs as $d )
  8. {
  9. if( is_dir($outerDir."/".$d) )
  10. {
  11. $dir_array[ $d ] = getDirectoryTree( $outerDir."/".$d );
  12. }
  13. else
  14. {
  15. $dir_array[] = $d;
  16. }
  17. }
  18. return $dir_array;
  19. }
  20.  
  21. $dirList = getDirectoryTree('.');
  22. $album = array_rand($dirList);
  23.  
  24. $countPhotos = count($dirList[$album]);
  25.  
  26. // Haal 4 random photos op
  27. for($i = 0; $i < 4; $i++)
  28. {
  29. $randomPhoto = rand(0, $countPhotos);
  30.  
  31. $file = $dirList[$album][$randomPhoto];
  32.  
  33. echo '<a title="Album: ' . $album . ' / Image ' . $file . '" href="albums/' . $album . '/' . $file . '">
  34. <img src="/thumbnail.php?im=albums/' . $album . '/' . $file . '" />
  35. </a>' . "\n";
  36. }
  37.  
  38. echo '<pre>' , var_dump( $album ) , '</pre>';
  39.  
  40. ?>
Offline snxs - 22/07/2009 00:39 (laatste wijziging 22/07/2009 00:41)
Avatar van snxs Nieuw lid En hoe werkt dit? Code:
  1. <?php
  2.  
  3. function getDirectoryTree( $outerDir )
  4. {
  5. $dirs = array_diff( scandir( $outerDir ), Array( ".", ".." ) );
  6. $dir_array = Array();
  7. foreach( $dirs as $d )
  8. {
  9. if( is_dir($outerDir."/".$d) )
  10. {
  11. $dir_array[ $d ] = getDirectoryTree( $outerDir."/".$d );
  12. }
  13. else
  14. {
  15. $dir_array[] = $d;
  16. }
  17. }
  18. return $dir_array;
  19. }
  20.  
  21. $dirList = getDirectoryTree('.');
  22. $album = array_rand($dirList);
  23.  
  24. // Haal 4 random photos op
  25. for($i = 0; $i < 4; $i++)
  26. {
  27. $file = array_rand($dirList[$album]);
  28.  
  29. echo '<a title="Album: ' . $album . ' / Image ' . $file . '" href="albums/' . $album . '/' . $file . '">
  30. <img src="/thumbnail.php?im=albums/' . $album . '/' . $file . '" />
  31. </a>' . "\n";
  32. }
  33.  
  34. echo '<pre>' , var_dump( $album ) , '</pre>';
  35.  
  36. ?>
Offline Martijn2008 - 22/07/2009 00:46
Avatar van Martijn2008 PHP beginner Op die code krijg ik een error:

  1. Warning: array_rand() [function.array-rand]: First argument has to be an array in /var/www/vhosts/test/albumParser.php on line 27


Ook komt het af en toe voor dat hij geen album selecteert. Op de laatste echo krijg ik dan `int(0)`. Eigenlijk zou er ook een een check ingebouwd moeten worden of er een .jpg image uit de map gehaald wordt en geen ander bestand. Want af en toe wordt er gewoon een dummy gereturned in value $file.

Offline snxs - 22/07/2009 01:12 (laatste wijziging 22/07/2009 01:16)
Avatar van snxs Nieuw lid Eerst; gebruik je oude code maar weer, en zet alles even op plaatscode.be

En als je lege results zou krijgen, zou dit betekenendat je functie getDirectoryTree niet goed is.

Probeer dit:
  1. <?php
  2. // ------------------------------------------------------------------------------------------------- //
  3. // - Read directory file by Guido Bouman v3.2 - //
  4. // ------------------------------------------------------------------------------------------------- //
  5. // - Usage: - //
  6. // - $dir - is the the dir that you want to search - //
  7. // - $type - What you expect to get back: files, dirs or both. - //
  8. // ------------------------------------------------------------------------------------------------- //
  9.  
  10. // - Read dir
  11. // --------------------------------------------------
  12. function read($dir,$type = ""){
  13. $files=array();
  14. $dirs=array();
  15.  
  16. $uitlees=opendir($dir);
  17. while(($result = readdir($uitlees))!= false)
  18. {
  19. if(is_file($dir."/".$result)){
  20. $files[] = $result;
  21. }elseif(is_dir($dir."/".$result)){
  22. if($result != "." && $result != ".."){
  23. $dirs[] = $result;
  24. }
  25. }
  26. }
  27. closedir($uitlees);
  28.  
  29. sort($files);
  30. sort($dirs);
  31.  
  32. if($type == "files"){
  33. return $files;
  34. }elseif($type == "dirs"){
  35. return $dirs;
  36. }elseif($type == "both" || empty($type)){
  37. return array_merge($dirs,$files);
  38. }
  39. }
  40. ?>


Dat is een directory functie die ik ooit geschreven heb, en die door de jaren heen een beetje gepolished is.

En:
  1. if( is_dir($outerDir."/".$d) )
  2. {
  3. $dir_array[ $d ] = getDirectoryTree( $outerDir."/".$d );
  4. }
  5. else
  6. {
  7. $dir_array[] = $d;
  8. }


Kun je beter vervangen voor:
  1. if( is_dir($outerDir."/".$d) )
  2. {
  3. $dir_array[ $d ] = getDirectoryTree( $outerDir."/".$d );
  4. }
  5. elseif( is_file($outerDir."/".$d) )
  6. {
  7. $dir_array[] = $d;
  8. }


Maar als je jouw array print, zie je dan lege resultaten? Dat kan toch niet?
Offline Martijn2008 - 22/07/2009 10:48 (laatste wijziging 22/07/2009 11:19)
Avatar van Martijn2008 PHP beginner Ja precies, dat klopt! Ik zie geen lege array resultaten. Beetje apart dus, dat er soms wel dummies returned worden.

Maar nu is alles dankzij jouw oplossing voor zover ik nu kan zien opgelost. Onwijs bedankt voor jouw hulp. Ik zal hieronder nog even werkende code plaatsen, zodat deze ook door andere gebruikt kan worden. Nogmaals hartstikke bedankt voor jouw hulp!

  1. <?php
  2.  
  3. function getDirectoryTree( $outerDir )
  4. {
  5. $dirs = array_diff( scandir( $outerDir ), Array( ".", ".." ) );
  6. $dir_array = Array();
  7. foreach( $dirs as $d )
  8. {
  9. if( is_dir($outerDir."/".$d) )
  10. {
  11. $dir_array[ $d ] = getDirectoryTree( $outerDir."/".$d );
  12. }
  13. elseif( is_file($outerDir."/".$d) )
  14. {
  15. $dir_array[ $d ] = $d;
  16. }
  17. }
  18. return $dir_array;
  19. }
  20.  
  21. $dirList = getDirectoryTree('.');
  22. $album = array_rand($dirList);
  23.  
  24. // Haal 4 random photos op
  25. for($i = 0; $i < 4; $i++)
  26. {
  27. $file = array_rand($dirList[$album]);
  28.  
  29. echo '<a title="Album: ' . $album . ' / Image ' . $file . '" href="/albums/' . $album . '/' . $file . '">
  30. <img src="/thumbnail.php?im=albums/' . $album . '/' . $file . '" />
  31. </a>' . "\n";
  32. }
  33.  
  34. echo '<pre>' , $album, '</pre>';
  35.  
  36. ?>
Gesponsorde links
Dit onderwerp is gesloten.
Actieve forumberichten
© 2002-2024 Sitemasters.be - Regels - Laadtijd: 0.733s