Volgend resultaat in een fetchObject() loop

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Sven de Haas

Sven de Haas

17/12/2014 17:18:03
Quote Anchor link
Als ik een loop heb van een fetchObject als deze:
Quote:
while($row = $objStmt->fetchObject())
{
echo($row->naam);
}


Kan ik dan in deze while loop ook bijv. de naam van de volgende record krijgen?
Dus dat hij dit weergeeft:

Naam: Jan
Volgende resultaat is: Kees

Zodat ik voordat hij naar het volgende resultaat gaat kan kijken wat daar in zit?
 
PHP hulp

PHP hulp

25/04/2024 23:50:05
 
- SanThe -

- SanThe -

17/12/2014 17:22:28
Quote Anchor link
En wat is het nut?
 
Sven de Haas

Sven de Haas

17/12/2014 17:40:20
Quote Anchor link
- SanThe - op 17/12/2014 17:22:28:
En wat is het nut?

Wat is het nut van jouw vraag?
 
Frank Nietbelangrijk

Frank Nietbelangrijk

17/12/2014 18:36:26
Quote Anchor link
Ja goed Sven zo kunnen we nog wel even doorgaan. Om jou een juist antwoord/advies te kunnen geven hebben we soms wat meer informatie nodig. Daarom is het van belang dat het voor ons duidelijk wordt wat je precies wilt bereiken. Wil je één record op een pagina tonen en alvast een idee geven van wat het volgende record is?

Dan zou je LIMIT kunnen gebruiken in je query:

LIMIT 0, 2 // eerste twee records: eerste is degene die je laat zien, de tweede is de volgende
LIMIT 1, 2 // tweede en derde record.
LIMIT 2, 2 // derde en vierde record.
LIMIT 3, 2 // vierde en vijfde record.
 
Sven de Haas

Sven de Haas

17/12/2014 19:35:27
Quote Anchor link
Frank Nietbelangrijk op 17/12/2014 18:36:26:
Ja goed Sven zo kunnen we nog wel even doorgaan. Om jou een juist antwoord/advies te kunnen geven hebben we soms wat meer informatie nodig. Daarom is het van belang dat het voor ons duidelijk wordt wat je precies wilt bereiken. Wil je één record op een pagina tonen en alvast een idee geven van wat het volgende record is?

Dan zou je LIMIT kunnen gebruiken in je query:

LIMIT 0, 2 // eerste twee records: eerste is degene die je laat zien, de tweede is de volgende
LIMIT 1, 2 // tweede en derde record.
LIMIT 2, 2 // derde en vierde record.
LIMIT 3, 2 // vierde en vijfde record.

Nee kijk. Dit voorbeeld toont het vorige en huidige resultaat:

Quote:
$objPDO = new clsPDO();
$objStmt = $objPDO->prepare('SELECT * FROM songhistory');

if($objStmt->execute())
{
$strPrevRow = '';

while($r = $objStmt->fetchObject())
{
if($strPrevRow != '')
echo('Vorig record is: '.$strPrevRow.'<br>');

echo('Huidig record is: '.$r['songtitle'].'<br><br>');

$strPrevRow = $r['songtitle'];
}
}


Maar nu wil ik ook de VOLGENDE van de loop gebruiken voor een handeling.
Dit heb ik nodig voor een songhistory class, als ik moet gaan uitleggen waarom ben ik wel even bezig, iets met vergelijken e.d. (Als de volgende hetzelfde is moet hij een handeling overslaan).
 
- SanThe -

- SanThe -

17/12/2014 19:44:12
Quote Anchor link
Sven de Haas op 17/12/2014 19:35:27:
(Als de volgende hetzelfde is moet hij een handeling overslaan).


Zitten er dan dubbele records in de database?
 
Joakim Broden

Joakim Broden

17/12/2014 20:38:34
Quote Anchor link
ipv volgend item moet je vorig item gebruiken, dus item opslaan in een var zoiets als:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
<?php
    $lastItem
= '';

    while($row = $objStmt->fetchObject()) {
        if ($lastItem != $row->naam) {
            echo $row->naam;
        }


        $lastItem = $row->naam;
    }

?>
 
Sven de Haas

Sven de Haas

17/12/2014 22:00:16
Quote Anchor link
Sabaton Joakim op 17/12/2014 20:38:34:
ipv volgend item moet je vorig item gebruiken, dus item opslaan in een var zoiets als:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
<?php
    $lastItem
= '';

    while($row = $objStmt->fetchObject()) {
        if ($lastItem != $row->naam) {
            echo $row->naam;
        }


        $lastItem = $row->naam;
    }

?>

Jij doet nu hetzelfde als ik in mijn script in mijn vorige post
Gewijzigd op 17/12/2014 22:00:50 door Sven de Haas
 
Joakim Broden

Joakim Broden

17/12/2014 22:32:25
Quote Anchor link
Ah sorry, had je post niet gelezen. Excuses.

Maar ik denk dat zoiets als onderstaande code zou kunnen werken (zo uit mijn hoofd, dus kan fouten bevatten). Anders zou je eventueel nog SQL JOINS kunnen werken om het voor elkaar te krijgen maar denk dat dit eerst even makkelijker is.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
    $items
= array();

    while($row = $objStmt->fetchObject()) {
        $items[] = $row;
    }


    for ($i = 0; $i < count($items); $i++) {
        if (isset($items[$i - 1])) {
            echo 'Vorig item: '.$items[$i - 1]->naam.'<br />';
        }


        echo 'Huidig item: '.$items[$i]->naam.'<br />';

        if (isset($items[$i + 1])) {
            echo 'Volgend item: '.$items[$i + 1]->naam.'<br />';
        }
    }

?>
Gewijzigd op 17/12/2014 22:32:59 door Joakim Broden
 
Sven de Haas

Sven de Haas

18/12/2014 09:25:41
Quote Anchor link
Sabaton Joakim op 17/12/2014 22:32:25:
Ah sorry, had je post niet gelezen. Excuses.

Maar ik denk dat zoiets als onderstaande code zou kunnen werken (zo uit mijn hoofd, dus kan fouten bevatten). Anders zou je eventueel nog SQL JOINS kunnen werken om het voor elkaar te krijgen maar denk dat dit eerst even makkelijker is.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
    $items
= array();

    while($row = $objStmt->fetchObject()) {
        $items[] = $row;
    }


    for ($i = 0; $i < count($items); $i++) {
        if (isset($items[$i - 1])) {
            echo 'Vorig item: '.$items[$i - 1]->naam.'<br />';
        }


        echo 'Huidig item: '.$items[$i]->naam.'<br />';

        if (isset($items[$i + 1])) {
            echo 'Volgend item: '.$items[$i + 1]->naam.'<br />';
        }
    }

?>

Haha ik dacht al zoiets :P
Dan zou dit inderdaad de enige mogelijkheid zijn.
Ik dacht dat er misschien een makkelijkere/mooiere oplossing voor was.

Toch bedankt voor de moeite! ;)
 
Willem vp

Willem vp

18/12/2014 10:07:05
Quote Anchor link
Het eenvoudigst lijkt me om een fetchAll() te doen. Je hebt dan je complete resultset in een array en dan is het een eitje om te kijken wat er in het volgende record zit.

Het nadeel is dat het wel meer geheugen kost, dus het hangt een beetje af van het aantal records en de recordgrootte of het handig is om dit te doen. Uiteraard kun je dat altijd zelf inperken door een LIMIT op te nemen in je query.
 
Sven de Haas

Sven de Haas

18/12/2014 12:10:01
Quote Anchor link
Willem vp op 18/12/2014 10:07:05:
Het eenvoudigst lijkt me om een fetchAll() te doen. Je hebt dan je complete resultset in een array en dan is het een eitje om te kijken wat er in het volgende record zit.

Het nadeel is dat het wel meer geheugen kost, dus het hangt een beetje af van het aantal records en de recordgrootte of het handig is om dit te doen. Uiteraard kun je dat altijd zelf inperken door een LIMIT op te nemen in je query.

Songhistory staat georderd per dag.
Zeg maar 450/500 records per pagina.
 
Willem vp

Willem vp

18/12/2014 12:59:27
Quote Anchor link
Zelf zou ik niet moeilijk doen over 500 records. Laten we even aannemen dat een record ongeveer 1 kB is (daar kun je al heel veel in kwijt) dan zou je dus een array van zo'n 500 kB hebben. Dat is niet iets waar PHP veel moeite mee zal hebben, tenzij je server heel erg krap in zijn geheugen zit. Maar als dat zo is, denk ik dat je een heel ander probleem hebt. ;-)
 
Sven de Haas

Sven de Haas

18/12/2014 13:25:51
Quote Anchor link
Willem vp op 18/12/2014 12:59:27:
Zelf zou ik niet moeilijk doen over 500 records. Laten we even aannemen dat een record ongeveer 1 kB is (daar kun je al heel veel in kwijt) dan zou je dus een array van zo'n 500 kB hebben. Dat is niet iets waar PHP veel moeite mee zal hebben, tenzij je server heel erg krap in zijn geheugen zit. Maar als dat zo is, denk ik dat je een heel ander probleem hebt. ;-)

Ja, en het gaat bij mij om een paar bytes per regel dus is er al helemaal niks aan de hand.
Hoe dan ook, het werkt met onderstaande code.
Dank voor u meedenken.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
if($objStmt->execute())
{

    $arrSonghistory = $objStmt->fetchAll(PDO::FETCH_OBJ);
    $intCounter = 0;
    
    foreach($arrSonghistory as $song)
    {

        if(isset($arrSonghistory[$intCounter-1]))
            echo('Vorige song was: '.$arrSonghistory[$intCounter-1]->song.'<br>');
        
        echo ('Huidige song is: ' . $song->song . '<br>');
        
        if(isset($arrSonghistory[$intCounter+1]))
            echo('Volgende song is: '.$arrSonghistory[$intCounter+1]->song.'<br>');
        
        echo ('<br>');
        
        $intCounter++;
    }
}

?>
Gewijzigd op 18/12/2014 13:36:15 door Sven de Haas
 
Willem vp

Willem vp

18/12/2014 15:24:32
Quote Anchor link
Nog een klein optimalisatiedingetje:

In de foreach-loop test je met isset() of een bepaald array-element bestaat. Het "probleem" is, dat een array dereference in PHP relatief duur is, door de manier waarop arrays zijn geïmplementeerd in PHP. Dit merk je vooral bij grote arrays.

Als je je loop iets sneller wilt maken (bij een array van deze omvang spreek je overigens denk ik over niet meer dan een tiende seconde, wellicht zelfs minder) dan zou je de issets nog kunnen vervangen door een check op $intCounter. De fetchAll geeft een sequentieel genummerde array terug die bij index 0 begint, dus je kan veilig aannemen dat als $intCounter > 0 is, er een vorig element is. En zolang $intCounter kleiner is dan het aantal array-elementen min 1, is er ook een volgend element. In code ziet dat er dan als volgt uit:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
if($objStmt->execute())
{

    $arrSonghistory = $objStmt->fetchAll(PDO::FETCH_OBJ);
    $intCounter = 0;
    $intRecordcount = count($arrSonghistory);
    
    foreach($arrSonghistory as $song)
    {

        if($intCounter > 0)
            echo('Vorige song was: '.$arrSonghistory[$intCounter-1]->song.'<br>');
        
        echo ('Huidige song is: ' . $song->song . '<br>');
        
        if($intCounter < $intRecordcount - 1)
            echo('Volgende song is: '.$arrSonghistory[$intCounter+1]->song.'<br>');
        
        echo ('<br>');
        
        $intCounter++;
    }
}

?>
 
Sven de Haas

Sven de Haas

18/12/2014 16:29:09
Quote Anchor link
Willem vp op 18/12/2014 15:24:32:
Nog een klein optimalisatiedingetje:

In de foreach-loop test je met isset() of een bepaald array-element bestaat. Het "probleem" is, dat een array dereference in PHP relatief duur is, door de manier waarop arrays zijn geïmplementeerd in PHP. Dit merk je vooral bij grote arrays.

Als je je loop iets sneller wilt maken (bij een array van deze omvang spreek je overigens denk ik over niet meer dan een tiende seconde, wellicht zelfs minder) dan zou je de issets nog kunnen vervangen door een check op $intCounter. De fetchAll geeft een sequentieel genummerde array terug die bij index 0 begint, dus je kan veilig aannemen dat als $intCounter > 0 is, er een vorig element is. En zolang $intCounter kleiner is dan het aantal array-elementen min 1, is er ook een volgend element. In code ziet dat er dan als volgt uit:

Bedankt voor je aanvulling. Dit is inderdaad een goed advies.
Het script was inmiddels al wat aangepast, eigenlijk was jou advies hier al in verwerkt. Echter niet met de $intCounter maar ik geef de key van de Array mee in de loop. Zie hier een gecomprimeerde versie van het huidige script:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
if($objStmt->execute())
{

    $arrSonghistory = $objStmt->fetchAll(PDO::FETCH_OBJ);
    $intCounter = 0;
    $intRecordcount = count($arrSonghistory);
    
    foreach($arrSonghistory as $intKey=>$arrSong)
    {

        if($intKey > 0)
            echo('Vorige song was: '.$arrSonghistory[$intCounter-1]->song.'<br>');
        
        echo ('Huidige song is: ' . $arrSong->song . '<br>');
        
        if($intKey < $intRecordcount - 1)
            echo('Volgende song is: '.$arrSonghistory[$intCounter+1]->song.'<br>');
        
        echo ('<br>');
    }
}

?>

Wanneer ik dit in de class verwerk werkt het correct waarvoor ik het nodig heb.
Gewijzigd op 18/12/2014 16:31:29 door Sven de Haas
 
Willem vp

Willem vp

18/12/2014 16:39:27
Quote Anchor link
Dit script gaat niet werken, maar ik ga ervan uit dat je het in de echte code wel goed hebt gedaan.

In deze snippet gebruik je namelijk nog $intCounter waar je $intKey moet/kan gebruiken. Omdat $intCounter niet wordt opgehoogd en dus 0 blijft, zal regel 11 altijd een foutmelding geven (invalid index -1) en regel 16 bijna altijd een verkeerde song (behalve bij het eerste record; daar gaat het per ongeluk goed).
 
Sven de Haas

Sven de Haas

18/12/2014 16:47:50
Quote Anchor link
Willem vp op 18/12/2014 16:39:27:
Dit script gaat niet werken, maar ik ga ervan uit dat je het in de echte code wel goed hebt gedaan.

In deze snippet gebruik je namelijk nog $intCounter waar je $intKey moet/kan gebruiken. Omdat $intCounter niet wordt opgehoogd en dus 0 blijft, zal regel 11 altijd een foutmelding geven (invalid index -1) en regel 16 bijna altijd een verkeerde song (behalve bij het eerste record; daar gaat het per ongeluk goed).

Klopt in had jou script even quick & dirty aangepast.
In het script sla ik namelijk de $intKey waar daadwerkelijk iets mee gedaan wordt op in een variabele. En deze is dan automatisch de vorige record. Dit doe ik omdat er soms een result wordt overgeslagen en daar dus niets mee gedaan mag/hoeft worden. Als ik dan terug ga in de array zelf dan pakt hij alsnog die onnodige record weer.

Zie hier de functie:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?php
if($objStmt->execute())
{

    $objNewSong = new clsSonghistoryItem();
    $arrSonghistory = $objStmt->fetchAll(PDO::FETCH_OBJ);
    
    $intLastAdd = '';
    $intRecordcount = count($arrSonghistory);
    
    foreach($arrSonghistory as $intKey=>$arrCurrSong)
    {

        if($intKey > 0)
        {

            if($intKey < ($intRecordcount-1))
            {

                $diffMinutes = $this->calcDifference($arrSonghistory[($intKey+1)]->date, $arrCurrSong->date);
                
                if($diffMinutes > 1)
                {

                    if($arrCurrSong->song != $arrSonghistory[$intLastAdd]->song)
                    {

                        $objNewSong->addSong($arrCurrSong->id, $arrCurrSong->viewDate, $arrCurrSong->song);
                        $intLastAdd = $intKey;
                    }
                }
            }

            else
            {
                if($arrCurrSong->song != $arrSonghistory[$intLastAdd]->song)
                {

                    $objNewSong->addSong($arrCurrSong->id, $arrCurrSong->viewDate, $arrCurrSong->song);
                    $intLastAdd = $intKey;
                }
            }
        }

        else
        {
            $objNewSong->addSong($arrCurrSong->id, $arrCurrSong->viewDate, $arrCurrSong->song);
            $intLastAdd = $intKey;
        }
    }

    
    $this->colSonghistory = $objNewSong->toArray();
}

?>
Gewijzigd op 18/12/2014 17:17:17 door Sven de Haas
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.