query met nuw_rows, bind_param en fetch_assoc
Los van elkaar wel, maar het lijkt me netter en sneller om alles in één te doen.
Dit is wat ik nu heb, maar op 1 of andere manier blijft het script $result als false zien, volgens diverse websites zou het toch zo moeten:
voorbeeld
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
$saltqry = "
SELECT
salt,
mw_gegevens_groep
FROM
mw_gegevens
WHERE
mw_gegevens_persnr = ?
";
if(!$statement = $connection->prepare($saltqry))
{
echo "Query error:.". $connection->error();
} else {
$statement->bind_param('i', $user);
$statement->execute();
$statement->store_result();
$rows = $statement->num_rows;
$result = $statement->get_result();
$saltuitkomst = $result->fetch_assoc();
}
?>
$saltqry = "
SELECT
salt,
mw_gegevens_groep
FROM
mw_gegevens
WHERE
mw_gegevens_persnr = ?
";
if(!$statement = $connection->prepare($saltqry))
{
echo "Query error:.". $connection->error();
} else {
$statement->bind_param('i', $user);
$statement->execute();
$statement->store_result();
$rows = $statement->num_rows;
$result = $statement->get_result();
$saltuitkomst = $result->fetch_assoc();
}
?>
Gewijzigd op 28/05/2016 20:12:03 door J C
Met store_result() heb je effectief de query-resultaten (resultset) overgeheveld van de database naar een stuk geheugen in PHP waarin deze query-resultaten worden opgeslagen, dit heet ook wel een buffered result set. Normaal zou je deze vervolgens
Wat je vervolgens doet is nogmaals proberen de resultset op te halen middels get_result(), maar deze had je dus al eerder van de database opgehaald als gevolg van een aanroep van store_result(). Aan de database-kant is dus geen data meer aanwezig waarschijnlijk.
Het artikel waar je naar linkt gaat o.a. over bind_result(), niet over store_result() en betreft
Oplossing: controleer of store_result() true oplevert en verwijder de aanroep van $result = $statement->get_result().
Een van de andere redenen dat ik prepared statements in MySQLi minder fijn vindt is dat je heel expliciet moet omgaan met queryresultaten waarbij je héél goed in de gaten moet houden of je gebruik maakt van (on)gebufferde resultsets.
Indien je gebruik maakt van ongebufferde resultsets kun je trouwens ook geen gebruik maken van methoden zoals num_rows() en data_seek() omdat de resultaten nog niet binnengehaald zijn door PHP maar record-gewijs worden overgeheveld van database naar PHP. PHP kan je dan niets vertellen over de totale omvang van een resultset en kan hier ook niet doorheen bladeren omdat deze simpelweg niet op voorhand alle resultaten tot zijn beschikking heeft.
Ook, als je 3x het bovenstaande hebt geschreven heb je hier toch schoon genoeg van? Schrijf, als je dan toch volhardt in de gebruikmaking van prepared statements icm MySQLi, een wrapper hiervoor zodat je het jezelf wat makkelijker maakt...
Tevens: waar komt $user vandaan en is dit ook een integer? Je controleert ook niet of het binden van de parameter is geslaagd...
Gewijzigd op 28/05/2016 20:29:29 door Thomas van den Heuvel
Thomas van den Heuvel op 28/05/2016 20:16:47:
Ik denk dat je hier een aantal dingen door elkaar gooit.
Met store_result() heb je effectief de query-resultaten (resultset) overgeheveld van de database naar een stuk geheugen in PHP waarin deze query-resultaten worden opgeslagen, dit heet ook wel een buffered result set. Normaal zou je deze vervolgens op kunnen halen met de fetch() methode.
Wat je vervolgens doet is nogmaals proberen de resultset op te halen middels get_result(), maar deze had je dus al eerder van de database opgehaald als gevolg van een aanroep van store_result(). Aan de database-kant is dus geen data meer aanwezig waarschijnlijk.
Met store_result() heb je effectief de query-resultaten (resultset) overgeheveld van de database naar een stuk geheugen in PHP waarin deze query-resultaten worden opgeslagen, dit heet ook wel een buffered result set. Normaal zou je deze vervolgens op kunnen halen met de fetch() methode.
Wat je vervolgens doet is nogmaals proberen de resultset op te halen middels get_result(), maar deze had je dus al eerder van de database opgehaald als gevolg van een aanroep van store_result(). Aan de database-kant is dus geen data meer aanwezig waarschijnlijk.
Ok dus die kanik dan weghalen, in dat geval kanik ook niet meet fetch_assoc gebruiken maar wordt het fetch. Zover was ik inmiddels.
Quote:
Het artikel waar je naar linkt gaat o.a. over bind_result(), niet over store_result() en betreft de verdere afhandeling van het verwerken van resultaten.
Het eerste stuk code wel, maar het tweede stuk code is nagenoeg hetzelfde als wat ik gebruik.
Quote:
Oplossing: controleer of store_result() true oplevert en verwijder de aanroep van $result = $statement->get_result().
Quote:
Een van de andere redenen dat ik prepared statements in MySQLi minder fijn vindt is dat je heel expliciet moet omgaan met queryresultaten waarbij je héél goed in de gaten moet houden of je gebruik maakt van (on)gebufferde resultsets. Indien je gebruik maakt van ongebufferde resultsets kun je trouwens ook geen gebruik maken van methoden zoals num_rows() en data_seek() omdat de resultaten nog niet binnengehaald zijn door PHP maar record-gewijs worden overgeheveld van database naar PHP.
Duidelijk
Quote:
Ook, als je 3x het bovenstaande hebt geschreven heb je hier toch schoon genoeg van? Schrijf, als je dan toch volhardt in de gebruikmaking van prepared statements icm MySQLi, een wrapper hiervoor zodat je het jezelf wat makkelijker maakt...
Dit snap ik niethelemaal, is een wrapper net zoiets als een variable die je steeds weer opnieuw kan oproepen (zoals in min voorbeeld $connection).
Ik heb daar eerder over gehoord, maar heb nog niet eerder een duidelijk uitleg ervan kunnen vinden.
Nu kopieer ik steeds het stukje tekst, als ik het ergens anders nodig heb.
Quote:
Tevens: waar komt $user vandaan en is dit ook een integer? Je controleert ook niet of het binden van de parameter is geslaagd...
$user is integer. Deze check wordt in het begin van het bestand gedaan via is_int($_POST[úser']).
Hoe check je het beste of het binden van de parameter is gelukt?
Zo iets?
Code (php)
Toevoeging op 28/05/2016 21:29:06:
HEt probleem leek opgelost. maar helaas toch nog niet helemaal.
Ik krijg niets terug uit de database, ik heb nu dit:
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
//check personal salt
$saltqry = "
SELECT
salt,
mw_gegevens_groep
FROM
mw_gegevens
WHERE
mw_gegevens_persnr = ?
";
if(!$statement = $connection->prepare($saltqry))
{
echo "Query error:.". $connection->error();
} else {
if(!$statement->bind_param('s', $user)){
echo "Not integer";
}else{
$statement->execute();
$statement->store_result();
$rows = $statement->num_rows;
$saltuitkomst = $statement->fetch();
}
}
?>
//check personal salt
$saltqry = "
SELECT
salt,
mw_gegevens_groep
FROM
mw_gegevens
WHERE
mw_gegevens_persnr = ?
";
if(!$statement = $connection->prepare($saltqry))
{
echo "Query error:.". $connection->error();
} else {
if(!$statement->bind_param('s', $user)){
echo "Not integer";
}else{
$statement->execute();
$statement->store_result();
$rows = $statement->num_rows;
$saltuitkomst = $statement->fetch();
}
}
?>
I fixed this with bind_result
Gewijzigd op 28/05/2016 22:34:05 door J C
Quote:
Nu kopieer ik steeds het stukje tekst, als ik het ergens anders nodig heb.
Een goed programmeerprincipe is "Don't repeat yourself". Als je eenzelfde handeling vaker uitvoert moet je hier iets mee doen, en daarmee bedoel ik niet knippen en plakken :).
Ben al de hele avond aan het zoeken naar een oplossing.
Ik weet dat het neit altijd handig is om * alle informatie uit een tabel te halen, maar in deze opzet vind ik het wel belangrijk dat alles binnengehaald wordt, ook als ik later nog een extra kollom toevoeg.
Dit werkt prima:
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
$mw_gegevens_qry = "
SELECT
*
FROM
mw_gegevens
WHERE
mw_gegevens_persnr=?
AND
mw_gegevens_pass=?
AND
mw_gegevens_pass!=''
";
$statement = $connection->prepare($mw_gegevens_qry);
if($qry === false){
echo "Query error:.". $connection->error();
}else{
$statement->bind_param('is', $user, $userpassword);
$statement->execute();
$result = $statement->get_result();
$mwgegevens = $result->fetch_assoc();
?>
$mw_gegevens_qry = "
SELECT
*
FROM
mw_gegevens
WHERE
mw_gegevens_persnr=?
AND
mw_gegevens_pass=?
AND
mw_gegevens_pass!=''
";
$statement = $connection->prepare($mw_gegevens_qry);
if($qry === false){
echo "Query error:.". $connection->error();
}else{
$statement->bind_param('is', $user, $userpassword);
$statement->execute();
$result = $statement->get_result();
$mwgegevens = $result->fetch_assoc();
?>
Maar zodra dit erbij komt krijg ik foutmeldingen:
$statement->store_result();
$rows = $statement->num_rows;
Quote:
Fatal error: Call to a member function fetch_assoc() on boolean
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
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
<?php
$mw_gegevens_qry = "
SELECT
*
FROM
mw_gegevens
WHERE
mw_gegevens_persnr=?
AND
mw_gegevens_pass=?
AND
mw_gegevens_pass!=''
";
$statement = $connection->prepare($mw_gegevens_qry);
if($qry === false){
echo "Query error:.". $connection->error();
}else{
$statement->bind_param('is', $user, $userpassword);
$statement->execute();
$statement->store_result();
$rows = $statement->num_rows;
$result = $statement->get_result();
$mwgegevens = $result->fetch_assoc();
if($rows == 0) {
$aErrors= 91;
}elseif($rows != 0 && $group==7){
$aErrors= 11;
}elseif($rows == 1){
$aErrors=0;
}else{
$aErrors=9999;
}
echo $mwgegevens['mw_gegevens_id'];
}
?>
$mw_gegevens_qry = "
SELECT
*
FROM
mw_gegevens
WHERE
mw_gegevens_persnr=?
AND
mw_gegevens_pass=?
AND
mw_gegevens_pass!=''
";
$statement = $connection->prepare($mw_gegevens_qry);
if($qry === false){
echo "Query error:.". $connection->error();
}else{
$statement->bind_param('is', $user, $userpassword);
$statement->execute();
$statement->store_result();
$rows = $statement->num_rows;
$result = $statement->get_result();
$mwgegevens = $result->fetch_assoc();
if($rows == 0) {
$aErrors= 91;
}elseif($rows != 0 && $group==7){
$aErrors= 11;
}elseif($rows == 1){
$aErrors=0;
}else{
$aErrors=9999;
}
echo $mwgegevens['mw_gegevens_id'];
}
?>
Gewijzigd op 29/05/2016 00:21:50 door J C
store_result() en get_result() doen min of meer hetzelfde, het enige wat verschilt is:
de returnwaarde
store_result() retourneert een boolean, get_result() retourneert een object van de klasse mysqli_result.
hoe je vervolgens de resultaten uitleest
Ingeval je store_result() gebruikt, roep je vervolgens de fetch() methode aan, maar dan moet je ook result-parameters binden blijkbaar om de resultaten echt te vangen, dit is wat nog ontbrak, maar dit is ook vele malen omslachtiger.
Ingeval je get_result() gebruikt, kun je op dit mysql_result object je favoriete fetch-methode loslaten en ook controleren uit hoeveel resultaten deze bestaat et cetera.
Wat jij probeert te doen is deze twee varianten combineren, en dat gaat gewoon niet.
Vergelijk het met de krant uit de brievenbus halen. De tweede keer dat je dit probeert zit er geen krant meer in de brievenbus.
Ik zou voor de get_result() variant gaan omdat deze wat intuïtiever werkt.
Of overstappen naar de variant van MySQLi die niet van prepared statements gebruik maakt, die werkt hetzelfde als de oorspronkelijke MySQL driver (de mysql_-functies).
Of overstappen op PDO als je prepared statements leuk vindt en je het jezelf moeilijker wilt maken om queries te debuggen :p.
Dit heb ik al uitgelegd: de returnwaarde
store_result() retourneert een boolean, get_result() retourneert een object van de klasse mysqli_result.
hoe je vervolgens de resultaten uitleest
Ingeval je store_result() gebruikt, roep je vervolgens de fetch() methode aan, maar dan moet je ook result-parameters binden blijkbaar om de resultaten echt te vangen, dit is wat nog ontbrak, maar dit is ook vele malen omslachtiger.
Ingeval je get_result() gebruikt, kun je op dit mysql_result object je favoriete fetch-methode loslaten en ook controleren uit hoeveel resultaten deze bestaat et cetera.
Wat jij probeert te doen is deze twee varianten combineren, en dat gaat gewoon niet.
Vergelijk het met de krant uit de brievenbus halen. De tweede keer dat je dit probeert zit er geen krant meer in de brievenbus.
Ik zou voor de get_result() variant gaan omdat deze wat intuïtiever werkt.
Of overstappen naar de variant van MySQLi die niet van prepared statements gebruik maakt, die werkt hetzelfde als de oorspronkelijke MySQL driver (de mysql_-functies).
Of overstappen op PDO als je prepared statements leuk vindt en je het jezelf moeilijker wilt maken om queries te debuggen :p.
Dank je wel, ik begrijp dat ik de 2 methodes niet kan combineren, maar ik krijg num_rows niet werkend zonder de store_result en krijg de fetch_assoc niet werkend zonder de get_result. Als ik echter probeer de get_result weg te halen en de fetch_assoc vervang door fetch, dan werkt het ook niet.
Voer het eens uit zoals je werkende voorbeeld, dus zonder store_result. De query an sich ziet er goed uit, en die geeft zo te zien ook geen foutmeldingen.
Ik vind het wel lastig de ene keer moet de store_result wel gebruikt worden en dan weer niet.
Gewijzigd op 29/05/2016 00:59:18 door J C
Quote:
maar ik krijg num_rows niet werkend zonder de store_result en krijg de fetch_assoc niet werkend zonder de get_result
:(
Ik leg hierboven precies uit wat in welk geval werkt. Een andere combinatie gaat niet lukken.
Indien dit te verwarrend voor je is stel ik voor dat je een van de alternatieven probeert.
Ik probeer nu ook verschillende combinaties uit om te kijken hoe ik het werkend kan krijgen.
PDO is voor mij niet echt een optie, daar ben ik mee begonnen, maar kwam er totaal niet uit.
MySQLi zonder statements zou eventueel nog wel een goede optie kunnen zijn.
Verschillende combinaties werken sowieso niet. Kies 1 ding en blijf daarbij. Wat begrijp je niet aan PDO? Het is mijn persoonlijke favoriet. Mogelijk omdat ik geen MySQL gebruik, al jaren niet.
Ik moest toen een beslissing maken en mysqli leek toen het makkelijkst.
Ik probeer het nu met num_rows, get_result en fetch_assoc.
Waarschijnlijk zit de fout in de volgorde.
Maar er zijn zoveel websites die dingen beschrijven, moeilijk om de goede eruit te halen.
Toevoeging op 29/05/2016 02:03:57:
het ziet er echter naar uit dat dit zo niet gaat lukken, dus denk dat ik het nu met 2 queries ga doen. 1 voor de aantal gegevens in de database en 1 om de inhoud eruit te halen.
Zet je error reporting eens aan:
error_reporting(E_ALL); ini_set('display_errors', 1); mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
error_reporting(E_ALL ^ E_DEPRECATED);
Ik ben ook bezig het script van deze website te kopieeren.
http://stackoverflow.com/questions/18753262/example-of-how-to-use-bind-result-vs-get-result
Gewijzigd op 29/05/2016 02:27:22 door J C
Gewijzigd op 29/05/2016 02:30:03 door Ben van Velzen
Fatal error: Call to a member function fetch_assoc() on boolean in /home/jcslnl/domains/jcsl.nl/public_html/medewerkers/includes/main.php on line 444
Misschien is dit voorbeeld verouderd
Toevoeging op 29/05/2016 02:39:26:
NA heel veel gedoe, hebik het eindelijk werkend. Ik heb geen idee waarom, maar het werkt.
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
$mw_gegevens_qry = "
SELECT
*
FROM
mw_gegevens
WHERE
mw_gegevens_persnr=?
AND
mw_gegevens_pass=?
AND
mw_gegevens_pass!=''
";
$statement = $connection->prepare($mw_gegevens_qry);
if($qry === false){
echo "Query error:.". $connection->error();
}else{
$statement->bind_param('is', $user, $userpassword);
$statement->execute();
$result = $statement->get_result();
$rows = $result->num_rows;
$mwgegevens = $result->fetch_assoc();
?>
$mw_gegevens_qry = "
SELECT
*
FROM
mw_gegevens
WHERE
mw_gegevens_persnr=?
AND
mw_gegevens_pass=?
AND
mw_gegevens_pass!=''
";
$statement = $connection->prepare($mw_gegevens_qry);
if($qry === false){
echo "Query error:.". $connection->error();
}else{
$statement->bind_param('is', $user, $userpassword);
$statement->execute();
$result = $statement->get_result();
$rows = $result->num_rows;
$mwgegevens = $result->fetch_assoc();
?>
Dus je doet precies wat ik zojuist omschreven heb. Verrassend dat dat werkt.
Behalve dat $rows = $statement->num_rows; moet worden aangepast naar $rows = $result->num_rows;
Precies wat ik zei toch? "Volgens jouw voorbeeldcode zou $result->num_rows een beter resultaat moeten leveren."
je hebt gelijk, ik had daar overheen gelezen.