Volgend resultaat in een fetchObject() loop
Quote:
while($row = $objStmt->fetchObject())
{
echo($row->naam);
}
{
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?
En wat is het nut?
- SanThe - op 17/12/2014 17:22:28:
En wat is het nut?
Wat is het nut van jouw vraag?
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.
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.
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'];
}
}
$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).
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?
Sabaton Joakim op 17/12/2014 20:38:34:
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
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)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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 />';
}
}
?>
$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
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.
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)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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 />';
}
}
?>
$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! ;)
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.
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.
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.
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. ;-)
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)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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++;
}
}
?>
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
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)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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++;
}
}
?>
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++;
}
}
?>
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:
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)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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>');
}
}
?>
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
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).
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).
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)
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
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();
}
?>
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