PDO vraagje
Als je dus een prepared statement uitvoert kan je niet het aantal resultaten van een resultaatset lezen. Ik zie in de tutorial dat je dan eerst een count() query moet uitvoeren maar het is toch niet efficient als je 2 queries uitvoert?
Ik zit dan te denken om voor select queries geen Prepared statement te gebruiken zoals hieronder:
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
<?php
//verinding maken etc..
$sql = "SELECT naam FROM tbl_persoon";
$results = $db->query($sql);
?>
//verinding maken etc..
$sql = "SELECT naam FROM tbl_persoon";
$results = $db->query($sql);
?>
zodat ik de rijen kan tellen, en voor insert, update en delete wel. Bij de select query zou ik dan wel quote()(of mysql_real_escape_string) moeten gebruiken om sql injectie tegen te gaan. Is dit een goede gedachte of heb ik iets verkeerd begrepen uit de tutorial?
Anders moet je gebruik maken van prepared statements. En die zorgen dat voor de mysq_real.. etc.
Martiveen - op 15/11/2012 12:41:44:
Zolang je geen user content invoegd.
Anders moet je gebruik maken van prepared statements. En die zorgen dat voor de mysq_real.. etc.
Anders moet je gebruik maken van prepared statements. En die zorgen dat voor de mysq_real.. etc.
Dus als ik het goed begrijp zijn prepared statements voornamelijk goed voor insert, update en delete? Maar voor select niet echt handig.
Hangt er vanaf of je user input gebruikt. Dan is het handig
Martiveen - op 15/11/2012 13:07:32:
Hangt er vanaf of je user input gebruikt. Dan is het handig
Dus als ik een query maak
Dan voer ik deze query toch maar 1 keer uit en dan heeft het toch niet echt nut om er een prepared statement van maak? Het enige voordeel wat ik dan zie van prepared statement is het feit dat je geen mysql_real_escape_string() hoeft te gebruiken volgens mij wordt het dan wel trager. Of is dit niet zo?
Voorbeeldje van PHP.net
Code (php)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
<?php
/* Execute a prepared statement by binding PHP variables */
$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour');
$sth->bindParam(':calories', $calories, PDO::PARAM_INT);
$sth->bindParam(':colour', $colour, PDO::PARAM_STR, 12);
$sth->execute();
?>
/* Execute a prepared statement by binding PHP variables */
$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour');
$sth->bindParam(':calories', $calories, PDO::PARAM_INT);
$sth->bindParam(':colour', $colour, PDO::PARAM_STR, 12);
$sth->execute();
?>
EDIT: linkje naar de code http://php.net/manual/en/pdostatement.bindparam.php
Gewijzigd op 15/11/2012 14:20:07 door Martiveen -
Martiveen - op 15/11/2012 14:17:00:
Nu gebruik je geen prepared statement.
Voorbeeldje van PHP.net
EDIT: linkje naar de code http://php.net/manual/en/pdostatement.bindparam.php
Voorbeeldje van PHP.net
Code (php)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
<?php
/* Execute a prepared statement by binding PHP variables */
$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour');
$sth->bindParam(':calories', $calories, PDO::PARAM_INT);
$sth->bindParam(':colour', $colour, PDO::PARAM_STR, 12);
$sth->execute();
?>
/* Execute a prepared statement by binding PHP variables */
$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour');
$sth->bindParam(':calories', $calories, PDO::PARAM_INT);
$sth->bindParam(':colour', $colour, PDO::PARAM_STR, 12);
$sth->execute();
?>
EDIT: linkje naar de code http://php.net/manual/en/pdostatement.bindparam.php
dat was ook mijn plan. Voor selects geen prepared statements en voor alle andere commando's wel :)
Je moet even alles wat je weet over mysql_* functies vergeten. Als je PDO gebruikt heb je deze niet meer nodig. Ook mysql_real_escape_string heb je niet meer nodig.
Ik zal even proberen uit te leggen in enkele stappen hoe je met PDO werk, om gegevens op te halen uit een database. Dit door gebruik te maken van prepared statements.
1) Verbinden met de database. Hiervoor gebruik je de variable $con.
2) De query schrijven:
Op de plaats waar je normaal user input* zo invoegen plaats je nu eerst een ':' en dan de een zelfgekozen duidelijke naam van die userinput. Omdat we hier een naam gaan invullen, neem ik ':naam';
3) De query 'preparen'. Nu wil ik even duidelijk maken waarom je de query moet preparen. We hebben hier een query met user input*. Stel we hebben een form met een input:
In dit input veld moet je je naam invullen. Deze naam wordt dan via $_POST doorgestuurd naar een .php bestand. Als je dan de query gaat opstellen krijg je dit: (een niet prepared query):
Deze query gaat het id uit de tabel users halen. Maar wat als ik nu mijn naam niet invul maar iets anders bv:
Ik heb nu i.p.v. een naam een query ingevuld. PHP gaat deze query ook uitvoeren. Alle users zijn nu verwijderd. Deze techniek die veel door hackers wordt gebruikt noemt men SQL injectie. (injection) Wat kan je nu doen omdat te voorkomen is alle tekens die door SQL in de query wordt gebruikt te gaan escapen, eigenlijk gewoon een \ voor gaan plaatsen. Daarvoor heb je bij mysql_* functies mysql_real_escape. Die gaat er dus voorzorgen dat er geen sql injectie mogelijk is.
De mensen die PDO hebben ontwikelt waren zo slim om dit anders aan te pakken. I.p.v. te escapen gaat PDO eerst de query versturen (preparen) en dan pas de user input, of de variable.
Zo prepare je een query:
We maken nu een nieuwe variable $q aan, en we gebruiken de varibale $con voor onze eerder gemaakte connectie, en $sql is onze query.
4) Nu hebben we natuurlijk geen user input of variable input gestuurd, dat gaan we nu doen. Dit kan op 2 manieren:
a. $q-execute(array(':naam', $_POST['naam']));
b. $q->bindParam(':naam', $_POST['naam']);
Beide manieren zijn juist, maar ik dacht dat je beter bindParam kan gebruiken. Waaorm weet ik niet zo direct.
5) De opgehaalde data laten zien. Dit doe je door te 'fetchen'=
In dit voorbeeld hebben we maar één rij opgehaald, als je meerdere rijen wilt ophalen doe je het zo:
Ik hoop dat alles duidelijk is. Anders vraag je het maar.
@De pro's. Ik denk dat alles wat ik geschreven heb juist, maar het kan natuurlijk dat er een foutje is ingeslopen.
*User input kan van alles zijn, meestal uit een form of uit de url, eigenlijk gewoon alles wat een gebruiker (user) kan invoegen(input)
Bedankt voor de duidelijke uitleg:
De reden dat ik DACHT dat ik bij selects beter geen prepared statements kon gebruiken was omdat ik in de tutorial het volgende las:
"In tegenstelling tot bijvoorbeeld de MySQLi extensie kent PDO geen methode om het aantal rijen in een resultaatset te bepalen."
Om dit dus te weten te komen moest er een extra query worden gemaakt en.. dat stond me eigenlijk tegen omdat ik dacht dat het qua snelheid niet zo goed ging (maar jij zegt nu dat dat eigenlijk niet uitmaakt tenzij je een robot bent maar dat zou dus geen probleem moeten zijn).
Waar ik dan wel aan zit te denken is dat je wel veel extra code moet schrijven alleen maar om te tellen hoeveel rijen er in een resultaatset zitten vandaar dat ik zo zit te twijfelen of ik PDO wel zo geschikt vond m.b.t. selects (daarvan wil ik vaak het aantal resultaten weten).
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
<?php
$sql = "SELECT naam FROM users"; // Hier gaan we de namen van alle users ophalen
$q = $con->prepare($sql);
$q->execute();
$rows = $q->fetchAll(); // Omdat we meerdere users hebben doen we fetchAll();
$count count($rows); // Nu gaan we het aantal rijen tellen en deze opslaan in $count
?>
$sql = "SELECT naam FROM users"; // Hier gaan we de namen van alle users ophalen
$q = $con->prepare($sql);
$q->execute();
$rows = $q->fetchAll(); // Omdat we meerdere users hebben doen we fetchAll();
$count count($rows); // Nu gaan we het aantal rijen tellen en deze opslaan in $count
?>
Waarschijnlijk wil je als er 1 of meer resultaten is/zijn de namen nog op het scherm tonen:
Code (php)
Gewijzigd op 15/11/2012 15:51:06 door LEDfan nvt
""In tegenstelling tot bijvoorbeeld de MySQLi extensie kent PDO geen methode om het aantal rijen in een resultaatset te bepalen.".
Maar aangezien je TOCH gewoon count() kan gebruiken heb ik nu geen reden meer om geen PDO te gebruiken. Hartstikke bedankt aan iedereen die hierin heeft gepost, ik denk dat ik nu wel weer vooruit kan :)
Nee dat kopt. PDO heeft geen mysql_num_rows o.i.d. maar zoals in mijn code kan je het zo oplossen.
hier mijn mening over preps al gegeven.
Als je alleen het aantal rijen wilt weten is het zelfs beter om COUNT(*) te gebruiken.
Ik heb Quote:
Maar aangezien je TOCH gewoon count() kan gebruiken heb ik nu geen reden meer om geen PDO te gebruiken. Hartstikke bedankt aan iedereen die hierin heeft gepost, ik denk dat ik nu wel weer vooruit kan :)
Als je alleen het aantal rijen wilt weten is het zelfs beter om COUNT(*) te gebruiken.
Ger van Steenderen op 15/11/2012 18:23:59:
Ik heb hier mijn mening over preps al gegeven.
Ik heb nu toevallig nodig dat ik een query meerdere keren uitvoer dus in dit geval is PDO wel de goede keuzen denk ik. Bij enkelvoudige queries zou ik mysqli kunnen gebruiken maar is het niet netter als je alles met 1 methode maakt (dus OF alleen PDO, of alleen mysqli?)
Ik zal niet een nieuw topic starten aangezien dit topic toch over PDO gaat.
Is het mogelijk om de pointer te resetten als ik
$row = $stmt->fetch(PDO::FETCH_ASSOC);
dus als ik de fetch functie gebruik zou ik graag later de pointer nog een keer naar het begin zetten. Ik heb al zitten zoeken maar ik kan het echt nergens vinden. Maar het lijkt mij sterk dat het niet mogelijk is? Weet iemand hoe ik dit voor elkaar krijg?
Gewijzigd op 09/12/2012 21:40:49 door ama saril