[PHP] Positie in array bepalen

Pagina: 1
Acties:
  • 149 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Martine
  • Registratie: Mei 2002
  • Niet online
Op een foto pagina komen aan beide kanten van een foto 'Vorige' en 'Volgende' te staan.

Je kan in het begin beginnen op de fotopagina maar, het kan ook zo zijn als je op de middelste foto komt en dan midden in de array komt.

Als ik bijvoorbeeld op foto nummer dcn_6010 start dan moet ik op vorige klikken en zo naar foto dcn_6009 gaan en als ik op volgende klik dan naar dnc_6011.

$path is /home/sites/blalbla/website/foto
$day is feest_kerstdagen, deze wordt in de url mee gegeven.
$foto is de betreffende foto die momenteel te zien is, deze wordt ook mee gegeven in de url.

Grote foto's hebben de naam dnc_xxxx.jpg en kleine foto's dnc_xxxx_klein.jpg

De onderstaande code heb ik. Hij lees alle bestanden uit waar niet _klein in de naam zit, deze stopt hij in een array.

Daarna kijkt waar de huidige foto zich bevindt in de array, op deze manier.
if ($array[$i] == htmlspecialchars($_GET['foto'])) {

Op die plaats moet de positie komen zodat ik met next(); naar de volgende foto kan, hoe los ik dit op?
Is met functie key(); de juiste oplossing?

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
    $dir_all = opendir($path."/".htmlspecialchars($_GET['day']));
    $array = array();
    
    while($file = readdir($dir_all)) {
        if(!eregi("_klein", $file)) {
            $newfile = explode(".", $file); // de .jpg eraf halen
            array_push($array, $newfile['0']);
        }
    }
    
        /** de mappen . en de .. eruit halen. **/
    $array = array_slice($array, 2);
    
    for($i=0;$i<count($array);$i++) {
        
        if ($array[$i] == htmlspecialchars($_GET['foto'])) {
            key($array);
            
            //echo $array[$i]." ->>> deze<br>"; // om te kijken
        }
        else {
            echo $array[$i]."<br>";
        }
    }
    
        /** Hela, het klopt niet...  :(  **/
    echo "de volgende: ".next($array);
?>

[ Voor 7% gewijzigd door Martine op 10-12-2005 02:46 ]


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 16:36
Waarom lees je de dir volledig in? Je weet welke foto je wil laten zien aan de hand van de GET parameter. Je weet welke de vorige en volgende moeten zijn. Het enige wat je dus hoeft te doen is checken of de vorige en volgende foto's bestaan...

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • Martine
  • Registratie: Mei 2002
  • Niet online
Maar hoe weet ik wat de volgende foto is?

Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 14:28
Dat kan alleen door een lijst te hebben van alle bestanden.

Acties:
  • 0 Henk 'm!

  • Johnny
  • Registratie: December 2001
  • Laatst online: 14:39

Johnny

ondergewaardeerde internetguru

djluc schreef op zaterdag 10 december 2005 @ 11:32:
Dat kan alleen door een lijst te hebben van alle bestanden.
Of door de foto's een logische naam te geven waarmee je de vorige en volgende aan kan afleiden. Als een foto 2 heet hoef je er alleen maar voor te zorgen dat die daarvoor en daarachter 1 en 3 zijn.

Aan de inhoud van de bovenstaande tekst kunnen geen rechten worden ontleend, tenzij dit expliciet in dit bericht is verwoord.


Acties:
  • 0 Henk 'm!

Verwijderd

Johnny schreef op zaterdag 10 december 2005 @ 11:39:

Of door de foto's een logische naam te geven waarmee je de vorige en volgende aan kan afleiden. Als een foto 2 heet hoef je er alleen maar voor te zorgen dat die daarvoor en daarachter 1 en 3 zijn.
En dat is iets minder handig, omdat je om welke reden dan ook weleens een foto zou kunnen verwijderen, en het is een beetje raar om dan de andere foto's te gaan renamen. Je kunt beter gewoon de volgende of vorige foto uit een verzameling (en dat kan een array zijn) nemen. En die verzameling kan uit een database komen, of uit een scriptje dat alle (foto)bestanden in een bepaalde directory in een array zet.

Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Ik heb ermee zitten priegelen en ben hier op gekomen:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<?php

function getPhotos($dir) {
    $dirHandle = opendir($dir);
    $photos = array();
    while ( $file = readdir($dirHandle) ) {
        if ( isValidPhotoFile($file) ) $photos[] = str_replace(".jpg", $file);
    }
    closedir($dirHandle);
    return $photos;
}

function isValidPhotoFile($file) {
    return !( eregi("_klein", $file) || $file == "." || $file == ".." );
}

function isCurrentPhoto($photo) {
    return $photo == htmlspecialchars($_GET['photo']);
}

function getCurrentPhotoIndex($photos) {
    foreach ( $photos as $index => $photo ) {
        if ( isCurrentPhoto($photo) ) return $index;
    }
}

function determineNextPhotoIndex($photos, $currentPhotoIndex) {
    $lastIndex = count($photos) - 1;
    $firstIndex = 0;
    return $currentPhotoIndex == $lastIndex ? $firstIndex : $currentPhotoIndex + 1;
}

function determinePreviousPhotoIndex($photos, $currentPhotoIndex) {
    $lastIndex = count($photos) - 1;
    $firstIndex = 0;
    return $currentPhotoIndex == $firstIndex ? $lastIndex : $currentPhotoIndex - 1;
}

$photoDirPath = $path . "/" . htmlspecialchars($_GET['day']);
$photos = getPhotos($photoDirPath);

$currentPhotoIndex = getCurrentPhotoIndex($photos);
$nextPhotoIndex = determineNextPhotoIndex($photos, $currentPhotoIndex);
$previousPhotoIndex = determinePreviousPhotoIndex($photos, $currentPhotoIndex);

$previousPhoto = $photos[$previousPhotoIndex];
$currentPhoto = $photos[$currentPhotoIndex];
$nextPhoto = $photos[$nextPhotoIndex];

?>
Vorige foto: <?=$previousPhoto?></br>
Huidige foto: <?=$currentPhoto?></br>
Volgende foto: <?=$nextPhoto?></br>

Ik heb het onderverdeeld in enkele logische stappen ingekapseld in losse functies. Jouw code werkt niet, omdat je de verkeerde verwachting hebt van de functie key(). Je denkt (denk ik ;)) dat die functie de huidige interne key verzet, naar de waarde van $i. Bij next zit je gewoon nog steeds aan het begin van de array, dus returned die logischerwijs het 2de element, en niet degene na de werkelijke huidige foto.

Hopelijk heb je iets aan mijn code, of helpt je het in de goede richting. Heb het niet getest overigens, waarschijnlijk zit er nog een foutje in ergens, dan moet je maar even debuggen. Success ermee iig.

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 16:36
Verwijderd schreef op zaterdag 10 december 2005 @ 11:45:
En dat is iets minder handig, omdat je om welke reden dan ook weleens een foto zou kunnen verwijderen, en het is een beetje raar om dan de andere foto's te gaan renamen. Je kunt beter gewoon de volgende of vorige foto uit een verzameling (en dat kan een array zijn) nemen. En die verzameling kan uit een database komen, of uit een scriptje dat alle (foto)bestanden in een bepaalde directory in een array zet.
Daar zit wat in, maar als je foto's in een directory staan hoef je bijna nooit alle bestanden in te lezen. Het voldoet bijvoorbeeld al om niet verder te lezen dan 1 foto na de huidige foto. Wanneer je foto's een vaststaand patroon hebben qua filename (CONST_INT.EXT ofzo) zijn er nog verdere optimalisaties mogelijk. De TS wekte op mij de indruk dat zijn bestandsnamen opvolgend waren, maar zelfs als er gaten in de nummering zitten ben je sneller uit door vanuit de huidige bestandsnaam omhoog en omlaag te zoeken naar de volgende en vorige.

Hoe dan ook vind ik het behoorlijk wat overhead om bij elke foto de complete dir af te scannen. Een index filetje of database zouden mijn voorkeur hebben.

@michali en TS: Om de bestandsextensie te strippen kun je beter geen explode() of str_replace() gebruiken maar strrpos(). Een bestandsnaam mag immers meerdere malen een punt bevatten, alleen de laatste punt onderscheidt de extensie.
PHP:
1
2
3
$extPos = strrpos($file, '.');
$fileWithoutExtension = substr($file, 0, $extPos);
$fileExtension = substr($file, $extPos+1);

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
@T-MOB: Klopt ja. Ik heb verder helemaal niets aan de methode van de TS veranderd, alleen de manier waarop het gedaan wordt. eregi("_klein", $file) is bijvoorbeeld ook niet netjes. Beter is om strpos("_klein", $file) !== false te gebruiken. En waarom de TS htmlspecialchars over de get vars photo en day haalt is me ook een raadsel.

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • chris
  • Registratie: September 2001
  • Laatst online: 11-03-2022
PHP komt met zo'n ontzettend arsenaal aan standaardfuncties, waarom dan niet gewoon pathinfo() gebruiken om achter de extensie te komen? Dan wordt die functie tenminste ook een keer gebruikt.

PHP:
1
2
3
4
function fileExtension($filename){
  $pathinfo= pathinfo($filename, PATHINFO_EXTENSION);
  return $pathinfo['extension'];
}

[ Voor 11% gewijzigd door chris op 10-12-2005 14:18 ]


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
chris schreef op zaterdag 10 december 2005 @ 14:17:
PHP komt met zo'n ontzettend arsenaal aan standaardfuncties, waarom dan niet gewoon pathinfo() gebruiken om achter de extensie te komen? Dan wordt die functie tenminste ook een keer gebruikt.
Ok, die kende ik niet, erg handig idd.

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • Martine
  • Registratie: Mei 2002
  • Niet online
Michali schreef op zaterdag 10 december 2005 @ 14:09:
En waarom de TS htmlspecialchars over de get vars photo en day haalt is me ook een raadsel.
Dit heb ik gedaan omdat deze te zien zijn in de url en mogelijk een <h1> mee te geven of iets dergelijks.

Verders kom ik er eigenlijk nog niet helemaal uit, hoe berekend hij nou de vorige foto?

[ Voor 26% gewijzigd door Martine op 12-12-2005 10:55 ]


Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 19:51

Creepy

Tactical Espionage Splatterer

Wat heb je nu dan wel? En wat lukt daar niet mee?

Er zijn al behoorlijk wat tips gegeven. Michali post zelfs een kant en klare oplossing. Met deze informatie lijkt het me dat je er wel uit moet kunnen komen. Als het niet lukt, geef dan precies aan wat er niet lukt en wat je zelf al hebt geprobeerd om het op te lossen. Een melding als "het lukt nog niet helemaal" zegt ons echt helemaal niks.

Dus toons eens wat meer inzet en laat geef nu precies aan wat er niet werkt (wat gebeurd er, hoe wijkt dat af van wat je had willen hebben) en geef daarbij de relevante code.

Want de positie van een bepaalde item in een array bepalen en dan de vorige en het volgende item ophalen is zo moeilijk nu ook weer niet.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Acties:
  • 0 Henk 'm!

  • Martine
  • Registratie: Mei 2002
  • Niet online
Ik had al de totale code al even geprobeerd maar er het werkt niet helemaal, maar in middels is het opgelost op deze manier.

Het werkt super, in ieder geval bedankt voor alle informatie!

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?
    $array = array();
    $dir_all = @opendir($path."/".htmlspecialchars($day));
    
    while($file = @readdir($dir_all)) {
        if(!eregi("_klein", $file)){
            $newfile = explode(".", $file);
            array_push($array, $newfile['0']);
        }
    }
    
    $array = @array_slice($array, 2);
    
    for($i=0;$i<count($array);$i++) {
        if ($array[$i] == htmlspecialchars($foto)) {
            $huidige = $i;
        }
    }
    
    if (empty($array[$huidige-1])) {
        $vorige = "Vorige";
    }
    else {
        $vorige = "<a href=\"?openfoto&foto=".$array[$huidige-1]."&day=".htmlspecialchars($_GET['day'])."\" title=\"Vorige foto\"><b>Vorige</b></a>";
    }
    
    if (empty($array[$huidige+1])) {
        $volgende = "Volgende";
    }
    else {
        $volgende = "<a href=\"?openfoto&foto=".$array[$huidige+1]."&day=".htmlspecialchars($_GET['day'])."\" title=\"Volgende foto\"><b>Volgende</b></a>";
    }
?>

Acties:
  • 0 Henk 'm!

  • Brakkie
  • Registratie: Maart 2001
  • Niet online

Brakkie

blaat

Wel jammer dat je het niet aanpakt zoals Michali je voorgeschoteld heeft. Dat is als je het mij vraagt erg nette code en die werkwijze kan je php code een stuk overzichtelijker maken.

Systeem | Strava


Acties:
  • 0 Henk 'm!

  • Martine
  • Registratie: Mei 2002
  • Niet online
Dat is waar, maar het zijn uiteindelijk maar twee loopje's...

Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Het is hoe dan ook good practice om heel communicerend te progammeren. Het is altijd goed om te proberen vanuit het oogpunt van iemand, die je code niet kent en het probeert te lezen, te kijken. Als je er zo over denkt en zaken probeert te verhelderen met extra functies en variabelen en eventueel betere naamgeving, dan verbeter je de kwaliteit van je code al een behoorlijk stuk. Dan is ook voor je zelf fijn. Als je na een half jaar je code bekijkt dan ben je blij als je het gestructueerd en duidelijk hebt gedaan. Je moet het niet te ver pushen natuurlijk, dat heeft alleen maar een averechts effect, maar het is wel goed om je er mee bezig te houden. Je kunt wel als argument gebruiken dat het simpel is, maar simpele zaken worden vaak uitgebreid met nog meer functionaliteit en als je het niet vanaf het begin netjes houd wordt het echt een onbeheersbare zooi uiteindelijk.

Ik zeg niet dat je gelijk heel fancy OO moet gaan proggen met verschillende lagen etc. dat is zwaar overdone voor een simpele applicatie. Beter is om de meest simpele oplossing te kiezen. Maar ook onder de simpele oplossingen kun je keuzes maken. Vaak is het goed om dan voor degene te gaan die het beste communiceert wat het doet en eventueel wat de intentie is. Dat kan, zoals ik in mijn voorbeeldje redelijk heb laten zien, ook heel goed puur met functies en variabelen.

[ Voor 10% gewijzigd door Michali op 12-12-2005 17:12 ]

Noushka's Magnificent Dream | Unity

Pagina: 1