query met nuw_rows, bind_param en fetch_assoc

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Pagina: 1 2 volgende »

J C

J C

28/05/2016 19:38:27
Quote Anchor link
Ik ben bezig met een query, waarin ik gebruik maak van nuw_rows, bind_param en fetch_assoc, maar krijg het niet goed werkend.

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)
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
$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
 
PHP hulp

PHP hulp

29/03/2024 14:10:46
 
Thomas van den Heuvel

Thomas van den Heuvel

28/05/2016 20:16:47
Quote Anchor link
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 uit kunnen lezen met 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.

Het artikel waar je naar linkt gaat o.a. over bind_result(), niet over store_result() en betreft de verdere een alternatieve afhandeling van het ophalen en verwerken van resultaten.

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
 
J C

J C

28/05/2016 20:37:13
Quote Anchor link
Dank je wel voor je uitgebreide antwoord.

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.

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().

Hiermee is het probleem ook opgelost.

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)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
<?php
if(!$statement->bind_param('s', $user);   )
{

//error message
}else{
//doorgaan met script
}
?>



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)
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
<?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();
                    }
                }

?>


I fixed this with bind_result
Gewijzigd op 28/05/2016 22:34:05 door J C
 
Thomas van den Heuvel

Thomas van den Heuvel

29/05/2016 00:15:13
Quote Anchor link
Is het nu opgelost of zijn er nog steeds problemen?

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 :).
 
J C

J C

29/05/2016 00:21:18
Quote Anchor link
Dit stukej werkt nu dankzij de bind_result, alleen kan ik dit niet toepassen op het andere stuk in het script.

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)
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
$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)
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
<?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'];
        }

?>
Gewijzigd op 29/05/2016 00:21:50 door J C
 
Thomas van den Heuvel

Thomas van den Heuvel

29/05/2016 00:38:41
Quote Anchor link
Dit heb ik al uitgelegd: 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.
 
J C

J C

29/05/2016 00:45:46
Quote Anchor link
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.
 
Ben van Velzen

Ben van Velzen

29/05/2016 00:47:12
Quote Anchor link
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.
 
J C

J C

29/05/2016 00:56:39
Quote Anchor link
ow het was inderdaad zo simpel. De resultaten worden nu wel weergegeven maar $rows is nu 0

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
 
Thomas van den Heuvel

Thomas van den Heuvel

29/05/2016 01:21:55
Quote Anchor link
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.
 
J C

J C

29/05/2016 01:28:59
Quote Anchor link
Sorry Ik probeer het te begrijpen, maar kom er nog niet helemaal uit.
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.
 
Ben van Velzen

Ben van Velzen

29/05/2016 01:52:03
Quote Anchor link
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.
 
J C

J C

29/05/2016 01:57:26
Quote Anchor link
OW dat is al lang geleden dat ik die keuze gemaakt heb.
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.
 
Ben van Velzen

Ben van Velzen

29/05/2016 02:20:46
Quote Anchor link
De num_rows komt uit een mysqli_result, zoveel is duidelijk uit de documentatie. Dus je moet deze niet uit je statement halen. Volgens jouw voorbeeldcode zou $result->num_rows een beter resultaat moeten leveren.
Zet je error reporting eens aan:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
<?php
error_reporting(E_ALL);
ini_set('display_errors', 'stdout');
?>
 
J C

J C

29/05/2016 02:23:45
Quote Anchor link
ik heb deze foutmelding, is dat ook goed?

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
 
Ben van Velzen

Ben van Velzen

29/05/2016 02:27:28
Quote Anchor link
De error reports zelf zouden daarmee goed moeten zijn, tenzij dit nu letterlijk je browser output is. Dan moet je het corrigeren. Het verandert echter niets aan de eerdere opmerking over $statement vs $result.
Gewijzigd op 29/05/2016 02:30:03 door Ben van Velzen
 
J C

J C

29/05/2016 02:31:30
Quote Anchor link
meestal kloppen de scripts op deze website wel, maar nu krijg ik toch weer dezelfde foutmelding die ik de hele dag al krijg

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)
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
$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();
?>
 
Ben van Velzen

Ben van Velzen

29/05/2016 02:43:37
Quote Anchor link
Dus je doet precies wat ik zojuist omschreven heb. Verrassend dat dat werkt.
 
J C

J C

29/05/2016 02:49:02
Quote Anchor link
Behalve dat $rows = $statement->num_rows; moet worden aangepast naar $rows = $result->num_rows;
 
Ben van Velzen

Ben van Velzen

29/05/2016 02:53:45
Quote Anchor link
Precies wat ik zei toch? "Volgens jouw voorbeeldcode zou $result->num_rows een beter resultaat moeten leveren."
 
J C

J C

29/05/2016 02:58:10
Quote Anchor link
je hebt gelijk, ik had daar overheen gelezen.
 

Pagina: 1 2 volgende »



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.