pdo execute
Hallo,
Aan de PDO execute functie kun je een array $input_parameters meegeven, bijv.
Ik vind dit wel een prettige manier. Je kan ook gebruik maken van bindParam() maar dan moet je telkens aangeven wat voor type variabele het is (bijv. een string of een int). Het meegeven van een array aan de execute functie vind ik prettiger werken.
Nu wordt er op php.net over deze array gezegd:
An array of values with as many elements as there are bound parameters in the SQL statement being executed. All values are treated as PDO::PARAM_STR.
Het gaat mij om het dikgedrukte stukje. Alle values worden als strings beschouwd. Echter, ik wil ook een getal kunnen ingeven (bijv. voor een id). Ik heb het even getest en dat lijkt gewoon goed te werken. Toch vind ik het raar dat die opmerking over die strings er dan bij staat vermeld. Heeft iemand een idee waarom die opmerking erbij staat, en kan dit op de een of andere manier voor problemen zorgen als ik een getal wil gebruiken?
Aan de PDO execute functie kun je een array $input_parameters meegeven, bijv.
Ik vind dit wel een prettige manier. Je kan ook gebruik maken van bindParam() maar dan moet je telkens aangeven wat voor type variabele het is (bijv. een string of een int). Het meegeven van een array aan de execute functie vind ik prettiger werken.
Nu wordt er op php.net over deze array gezegd:
An array of values with as many elements as there are bound parameters in the SQL statement being executed. All values are treated as PDO::PARAM_STR.
Het gaat mij om het dikgedrukte stukje. Alle values worden als strings beschouwd. Echter, ik wil ook een getal kunnen ingeven (bijv. voor een id). Ik heb het even getest en dat lijkt gewoon goed te werken. Toch vind ik het raar dat die opmerking over die strings er dan bij staat vermeld. Heeft iemand een idee waarom die opmerking erbij staat, en kan dit op de een of andere manier voor problemen zorgen als ik een getal wil gebruiken?
Dat is nogal logisch en je hebt in feite zelf het antwoord al gegeven:
In bindparam kan je aangeven wat voor type het is. Dat is het voordeel van bindparam. Als je het in execute meegeeft kan je dat niet en DUS moet alles op een identieke wijze worden verwerkt. De database engine kan niet ruiken wanneer jij een string bedoelt en wanneer jij een integer bedoelt. Alles is dus automatisch een string.
Wil je specifiek een integer invoeren, dan gebruik je dus bindparam.
Of het voor problemen kan zorgen durf ik niet 100% te zeggen. In principe niet denk ik, aangezien je een waarde altijd binnen quotes kan meegeven in een query. Niet nodig en in veel gevallen ook overbodig, maar het kan wel. Geef je een integer mee binnen quotes dan krijg je er niet eens een warning voor.
Toevoeging op 08/05/2013 10:52:00:
Edit:
De situatie waar je normaal geproken wilt dat een integer bijvoorbeeld NIET tussen quotes staat is voor het voorkomen van sql-injectie. Als je een int waarde zonder quotes geeft en het is een echte int dan gaat je query goed. Geef je het zonder quotes mee en staat er iets anders in, dan krijg je een error uit je database, query wordt niet uitgevoerd. Geef je echter een int tussen quotes op en staat er dan iets vreemds in, dan kan het wel uitgevoerd worden!
Echter, deze situatie is in jouw geval niet van toepassing omdat je een prepared statement gebruikt.
Ozzie PHP op 08/05/2013 03:33:50:
Je kan ook gebruik maken van bindParam() maar dan moet je telkens aangeven wat voor type variabele het is (bijv. een string of een int).
In bindparam kan je aangeven wat voor type het is. Dat is het voordeel van bindparam. Als je het in execute meegeeft kan je dat niet en DUS moet alles op een identieke wijze worden verwerkt. De database engine kan niet ruiken wanneer jij een string bedoelt en wanneer jij een integer bedoelt. Alles is dus automatisch een string.
Wil je specifiek een integer invoeren, dan gebruik je dus bindparam.
Of het voor problemen kan zorgen durf ik niet 100% te zeggen. In principe niet denk ik, aangezien je een waarde altijd binnen quotes kan meegeven in een query. Niet nodig en in veel gevallen ook overbodig, maar het kan wel. Geef je een integer mee binnen quotes dan krijg je er niet eens een warning voor.
Toevoeging op 08/05/2013 10:52:00:
Edit:
De situatie waar je normaal geproken wilt dat een integer bijvoorbeeld NIET tussen quotes staat is voor het voorkomen van sql-injectie. Als je een int waarde zonder quotes geeft en het is een echte int dan gaat je query goed. Geef je het zonder quotes mee en staat er iets anders in, dan krijg je een error uit je database, query wordt niet uitgevoerd. Geef je echter een int tussen quotes op en staat er dan iets vreemds in, dan kan het wel uitgevoerd worden!
Echter, deze situatie is in jouw geval niet van toepassing omdat je een prepared statement gebruikt.
Bij int en string maakt het niet heel veel uit. Maar types al bool of null maakt dit wel uit.
Dankjulliewel.
In welke situatie zou dit voor problemen kunnen zorgen? Kan iemand een voorbeeld geven?
Wouter J op 08/05/2013 11:34:42:
Bij int en string maakt het niet heel veel uit. Maar types al bool of null maakt dit wel uit.
In welke situatie zou dit voor problemen kunnen zorgen? Kan iemand een voorbeeld geven?
Bij MySQL maakt het inderdaad niet uit, bij SQL Server wel, daar krijg je een foutmelding als je een numeriek datatype quote. MySQL kent (net als de SQL standaard) overigens geen boolean datatype.
Thanks Ger, ik zal al te zoeken naar een boolean datatype maar ik kon niks vinden. Dat verklaart nu ook waarom :)
Maar is het dan "fout" om een numeriek datatype te quoten?
Hoe dan ook, is de manier waarop ik het nu doe 100% veilig? Ik maak dus gebruik van prepared statements, en ik geef de parameters als array mee in de execute() method. Of zeggen jullie dat ik toch beter bindParam() kan gebruiken? Is er een wezenlijk verschil?
Maar is het dan "fout" om een numeriek datatype te quoten?
Hoe dan ook, is de manier waarop ik het nu doe 100% veilig? Ik maak dus gebruik van prepared statements, en ik geef de parameters als array mee in de execute() method. Of zeggen jullie dat ik toch beter bindParam() kan gebruiken? Is er een wezenlijk verschil?
Ik heb pas PDO op school gehad, maar is het niet gewoon zo:
Ozzie PHP op 08/05/2013 13:08:16:
Maar is het dan "fout" om een numeriek datatype te quoten?
Nee fout is het niet, ik vind het alleen niet in overeenstemming met de gedachte van portabilty achter PDO.
Dus als ik al prepared statements zou gebruiken (wat ik zeer zelden doe) dan zou ik met bindParam werken.
Laat ik mijn vraag dan anders formuleren. Het feit dat ik geen datatype meegeef (omdat ik een array meegeef aan de execute() method) kan dat op de een of andere manier negatieve gevolgen hebben? Queries die niet werken, slechtere performance?
(Ik zou bijv. ook een functie kunnen maken waarbij ik een array meegeef en dat ik dan per key/value paar kijk welk datatype de value is, en afhankelijk daarvan bindParam aanroep met het juiste datatype. Maar wellicht is dit nogal over de top.)
(Ik zou bijv. ook een functie kunnen maken waarbij ik een array meegeef en dat ik dan per key/value paar kijk welk datatype de value is, en afhankelijk daarvan bindParam aanroep met het juiste datatype. Maar wellicht is dit nogal over de top.)
Gewijzigd op 08/05/2013 13:31:48 door Ozzie PHP
Nee met Mysql dus niet. In ieder geval geen foutmelding op de query, en mocht er al performance verlies zijn dan is dat te verwaarlozen.
Oké, thanks Ger. En het idee om een array via een method om te zetten naar bindParam() met het juiste datatype? Wat vind je daarvan?
Zou dat enige toegevoegde waarde hebben? Of is het dan toch beter om gewoon een array zonder datatypes mee te geven aan execute()?
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
<?php
$foo = 'een string';
$bar = 10;
$array = array(':foo' => $foo, ':bar' => $bar);
// en dat je deze array dan omzet naar:
bindParam(':foo', $foo, PDO::PARAM_STR);
bindParam(':bar', $bar, PDO::PARAM_INT);
?>
$foo = 'een string';
$bar = 10;
$array = array(':foo' => $foo, ':bar' => $bar);
// en dat je deze array dan omzet naar:
bindParam(':foo', $foo, PDO::PARAM_STR);
bindParam(':bar', $bar, PDO::PARAM_INT);
?>
Zou dat enige toegevoegde waarde hebben? Of is het dan toch beter om gewoon een array zonder datatypes mee te geven aan execute()?
Gewijzigd op 08/05/2013 13:47:19 door Ozzie PHP
Ik vind dat een goed idee, maar ik ben dan ook een purist in dat soort dingen.
Ik loop nog steeds met het idee rond om een 'eigen' parameter methode te ontwikkelen, met als voorbeeld de bind methode van .NET. Daar kan je alle datatypes aan een parameter toewijzen, en owee als je dan een string aan een int parameter meegeeft.
Ik loop nog steeds met het idee rond om een 'eigen' parameter methode te ontwikkelen, met als voorbeeld de bind methode van .NET. Daar kan je alle datatypes aan een parameter toewijzen, en owee als je dan een string aan een int parameter meegeeft.
Oké, thanks... het enige nadeel is dat er dan wat meer processing plaats moet vinden wat weer nadelig kan zijn voor je performance. Maar van de andere kant doe je ook weer niet heeel veel queries per pagina.
Toevoeging op 08/05/2013 14:32:28:
Toch een probleem als je alleen de execute array gebruikt.
Als je bijv. "... LIMIT :limit_amount" wil doen dan mogen daar geen quotes omheen staan. De query zal dan mislukken.
Toevoeging op 08/05/2013 14:32:28:
Toch een probleem als je alleen de execute array gebruikt.
Als je bijv. "... LIMIT :limit_amount" wil doen dan mogen daar geen quotes omheen staan. De query zal dan mislukken.
Ik zou zeggen dat je bindParam niet hoeft te gebruiken zolang je de variabelen vantevoren al correct getypecast hebt.
Dus je wilt een id als int opslaan, dan ook altijd netjes $iId = (int) 1 ;
Je komt pas in de problemen als je applicaties groeien en daarmee de kans op slordigheidjes vergroot, dus per ongeluk toch een numerieke string voor id in de database plempen.
Dus je wilt een id als int opslaan, dan ook altijd netjes $iId = (int) 1 ;
Je komt pas in de problemen als je applicaties groeien en daarmee de kans op slordigheidjes vergroot, dus per ongeluk toch een numerieke string voor id in de database plempen.
Zie mijn opmerking hierboven... als ik een LIMIT wil meegeven en ik dat via de array doe, dan wordt er een string van gemaakt en gaat het fout want dat mag niet in MySQL :(
Wat heeft het voor zin een parameter aan een LIMIT te geven?
Bijv. om in te stellen hoeveel rijen je wilt terugkrijgen?
Ja hehehe dat snap ik, maar waarom in een parameter
Maar prepared statements zijn hoofdzakelijk bedoeld om je performance te verbeteren als je meerdere dezelfde query's achter elkaar uit moet voeren met verschillende waarden in de parameters.
Maar bij één enkele levert het performance verlies op (dat vind vooral jij niet zo leuk).
Maar prepared statements zijn hoofdzakelijk bedoeld om je performance te verbeteren als je meerdere dezelfde query's achter elkaar uit moet voeren met verschillende waarden in de parameters.
Maar bij één enkele levert het performance verlies op (dat vind vooral jij niet zo leuk).
Gewijzigd op 08/05/2013 16:18:04 door Ger van Steenderen
"Ja hehehe dat snap ik, maar waarom in een parameter"
Omdat ie dan ge-escaped wordt enzo? Dus veilig? Maar "limit" kan toch ook gewoon een parameter zijn? Of zie ik dat verkeerd?
"Maar prepared statements zijn hoofdzakelijk bedoeld om je performance te verbeteren als je meerdere dezelfde query's achter elkaar uit moet voeren met verschillende waarden in de parameters."
Is het echt meetbaar trager dan? Ik begreep juist dat het veiliger is om prepared statements te gebruiken ivm sql injection. Dus vandaar leek het me eigenlijk wel oké. Zit ik ernaast?
Omdat ie dan ge-escaped wordt enzo? Dus veilig? Maar "limit" kan toch ook gewoon een parameter zijn? Of zie ik dat verkeerd?
"Maar prepared statements zijn hoofdzakelijk bedoeld om je performance te verbeteren als je meerdere dezelfde query's achter elkaar uit moet voeren met verschillende waarden in de parameters."
Is het echt meetbaar trager dan? Ik begreep juist dat het veiliger is om prepared statements te gebruiken ivm sql injection. Dus vandaar leek het me eigenlijk wel oké. Zit ik ernaast?
Veiliger dan wat? Ja, met prepared statements kan je geen sql injectie meer krijgen. Maar als jij je input goed controleert en bijvoorbeeld pdo.quote gebruikt, dan kan dat ook niet.
Maar bij een limit kan het eigenlijk ook al niet. Zoals jezelf eerder al aangaf kan je bij een limit geen quotes om de waarde heenzetten. Dus deze query gaat niet werken:
Daarnaast kan je geen twee queries in 1 keer uitvoeren, dus dit kan ook niet:
Ergo: via die limit clause kan je helemaal geen sql injectie krijgen. Ook geen noodzaak dus om daar prepared statements te gebruiken.
Maar bij een limit kan het eigenlijk ook al niet. Zoals jezelf eerder al aangaf kan je bij een limit geen quotes om de waarde heenzetten. Dus deze query gaat niet werken:
Daarnaast kan je geen twee queries in 1 keer uitvoeren, dus dit kan ook niet:
Ergo: via die limit clause kan je helemaal geen sql injectie krijgen. Ook geen noodzaak dus om daar prepared statements te gebruiken.
Erwin, dankjewel voor je toelichting. Maar kan het dan kwaad als ik prepared statements gebruik? Het lijkt nu alsof jullie zeggen dat het niet goed is.
Daarnaast vind ik het wel duidelijker om prepared statements te gebruiken omdat je dan niet al je values hoeft te gaan quoten. Dat heeft ook wel weer z'n voordelen.
Maar ik zou graag weten waarom het niet oké is om prepared statements te gebruiken.
Daarnaast vind ik het wel duidelijker om prepared statements te gebruiken omdat je dan niet al je values hoeft te gaan quoten. Dat heeft ook wel weer z'n voordelen.
Maar ik zou graag weten waarom het niet oké is om prepared statements te gebruiken.




