stmt vs prep stmt
Ik heb mijn class nu zo gemaakt, dat ik heel makkelijk kan switchen tussen het gebruik van normale en prepared statements. Voor statements die maar 1 keer te hoeven worden uitgevoerd, gebruik ik dan gewoon een normaal statement. Er valt mij echter wel iets op.
Als ik gebruik maak van prepared statements en ik daarbij de bindValue() method gebruik, dan kun je per value meegeven om wat voor soort data type het gaat, bijv. een integer, string, boolean of null.
Als ik echter gebruik maak van een normale statement dan kun je geen data types aangeven. Het enige wat je kunt doen is de quote() method gebruiken om strings te quoten.
Nu vroeg ik me af waarom dit zo is, en mijn conclusie is:
Bij een normaal statement wordt verwacht dat je zelf de quotes goed zet, in de query zelf. Op het moment dat je een variabele in de query plaatst en dit een string is, dan dien je deze string te quoten. Bij een prepared statement gebruik je placeholders en geef je aan van wat voor data type een bepaalde value is en vervolgens weet PDO dan of er wel of niet gequote moet worden. Begrijp ik het zo goed???
Als laatste ben ik ook wel benieuwd hoe vaak en wanneer jullie gebruik maken van een prepared statement. In feite zou je een prepared statement dus alleen moeten gebruiken op het moment dat je hetzelfde statement meerdere keren wilt uitvoeren, maar met verschillende waarden. Maar in welke situaties komt dit eigenlijk voor? Stel dat je met een query de gegevens wil ophalen van personen met de voornaam Jan, Piet en Kees. Dit zou je makkelijk in 1 query kunnen doen, maar is het nu de bedoeling dat je dat dan voortaan met een prepared statement doet, waarbij je telkens de naam wijzigt?
Ozzie PHP op 27/05/2013 14:33:30:
Een tijdje geleden heb ik ook al eens gevraagd hoe het nu zit met prepared statements. Bijna overal lees je dat je altijd prepared statements moet gebruiken omdat dat veiliger zou zijn. Echter, hier op het forum werd gezegd dat je voor queries die je eenmalig uitvoert beter "normale" statements kunt gebruiken omdat dat beter is voor de performance.
Het gebruik van het woord 'echter' suggereert dat de tweede bewering in tegenspraak zou zijn met de eerste. Dit is echter niet het geval.
Ja, prepared statements zijn veiliger (denk aan SQL injection).
Ja, soms is het voor de performance beter om geen prepared statements te gebruiken.
Wat je je moet afvragen is, wat je belangrijker vindt. Zelf vind ik een gehackte website altijd zeer nadelig voor de performance. In dat licht kan het ook voor de performance wel eens beter zijn om alleen prepared statements te gebruiken. ;-)
En aan de andere kant: waar praten we nu helemaal over? Ik heb hier een script dat een stuk of 10 prepared statements aanmaakt en daarop wat queries uitvoert. Als ik het opstart, heb ik niet eens tijd om met mijn ogen te knipperen voor het is afgelopen. Zo erg nadelig voor de performance is het dus ook weer niet. Je moet uiteraard niet in een loopje gaat lopen preparen, maar dat is ook niet de gedachte achter prepared statements.
Quote:
Als ik gebruik maak van prepared statements en ik daarbij de bindValue() method gebruik, dan kun je per value meegeven om wat voor soort data type het gaat, bijv. een integer, string, boolean of null.
null values en prepared statements zijn een verhaal op zich. ;-) Als de database engine zich aan de SQL-standaard houdt, kun je namelijk niet zomaar een null als parameter meegeven aan een select statement, bijvoorbeeld.
Quote:
Bij een normaal statement wordt verwacht dat je zelf de quotes goed zet, in de query zelf. Op het moment dat je een variabele in de query plaatst en dit een string is, dan dien je deze string te quoten. Bij een prepared statement gebruik je placeholders en geef je aan van wat voor data type een bepaalde value is en vervolgens weet PDO dan of er wel of niet gequote moet worden. Begrijp ik het zo goed???
Ongetwijfeld valt er nog iets te nuanceren, maar ik vind dat je het zo wel mooi hebt samengevat.
Quote:
Als laatste ben ik ook wel benieuwd hoe vaak en wanneer jullie gebruik maken van een prepared statement. In feite zou je een prepared statement dus alleen moeten gebruiken op het moment dat je hetzelfde statement meerdere keren wilt uitvoeren, maar met verschillende waarden. Maar in welke situaties komt dit eigenlijk voor?
Het hangt een beetje van het toepassingsgebied af. Bij webpagina's wordt de pagina opgebouwd en vervolgens ben je klaar. Bij een nieuwe request moet alles weer overnieuw gedaan worden. Wanneer je echter software maakt die langer draait dan die halve seconde die nodig is om een webpagina op te bouwen, zul je meer plezier hebben van prepared statements. Bij websites zul je ze voornamelijk gebruiken omdat je je dan minder druk hoeft te maken over SQL injection.
Gewijzigd op 27/05/2013 15:59:10 door Willem vp
Bij mij gaat het inderdaad om websites en niet om software die langdurig draait.
Ik heb een functie gemaakt waarmee ik gewoon een prepared statement kan maken, bijv.
SELECT foo WHERE bar = :bar
Values toevoegen:
setValues('bar' => $bar);
Wat ik nu doe is het volgende. Indien de query meerdere keren moet worden uitgevoerd, dan roep ik eerst een functie aan waarmee ik aangeef dat ik een prepared statement wil gebruiken. Vervolgens wordt er dan achter de schermen ook daadwerkelijk een prepared statement gebruikt. Als ik deze functie niet aanroep dan wordt een "normale" statement gebruikt.
In het bovenstaande voorbeeld houdt dit het volgende in:
- ik bepaal of $bar een string is. Zo ja, dan quote ik deze value quote($bar)
- ik vervang :bar in de query door de value $bar
Volgens mij ben ik dan ook veilig voor SQL-injectie, maar gebruik ik geen prepared statement.
Ozzie PHP op 27/05/2013 14:33:30:
Als laatste ben ik ook wel benieuwd hoe vaak en wanneer jullie gebruik maken van een prepared statement. In feite zou je een prepared statement dus alleen moeten gebruiken op het moment dat je hetzelfde statement meerdere keren wilt uitvoeren, maar met verschillende waarden. Maar in welke situaties komt dit eigenlijk voor? Stel dat je met een query de gegevens wil ophalen van personen met de voornaam Jan, Piet en Kees. Dit zou je makkelijk in 1 query kunnen doen, maar is het nu de bedoeling dat je dat dan voortaan met een prepared statement doet, waarbij je telkens de naam wijzigt?
Als je het in één query kan doen, moet je het niet in meerdere query's doen, ook niet met preps.
Met een prepared statement spreekt de client (PDO/MySQLi) de api van de database server aan, en 'vertelt' dat er een query aankomt met een aantal variabelen (parameters). De server maakt dan een execution plan voor de query en geeft de client een pointer terug. Daarna hoeven enkel maar de parameters voor die pointer aan de db server doorgeven te worden.
Maar het is niet de prepared statement dat sql injectie voorkomt maar de parameters,
en het is mij volledig onduidelijk waarom de laatse niet zonder de eerste kan in PDO en MySQLi.
Op de vraag hoe vaak en wanneer ik prepared statements gebruik:
Zelden, alleen bij updates en in MySQL bij sommige selects.
Ik vind het vrij lastig allemaal. Ook het bindValue() verhaal. Als ik wil dat een variabele als een integer wordt beschouwd via PDO::PARAM_INT, dus zo:
bindValue('foo', $foo, PDO::PARAM_INT);
Is het dan de bedoeling dat $foo ook daadwerkelijk een integer is, bijv. 12. Of mag het ook een numerieke string zijn, bijv. "12"?