• Hallo iedereen,


    Ik heb dus een vraagje, aangezien we aan een project voor onszelf bezig zijn en dit zo professioneel mogelijk willen maken, met misschien tot doel dit later te verkopen.
    Ik vroeg mij dus af, of ik dan het beste in PDO of MySQLi werk voor performantie en beveiliging, of is dit gewoon persoonlijke voorkeur?
    Indien ik de data die binnenkomt controleer en escape, is dit dan genoeg? Of zijn prepared statements echt een must?


    Alvast bedankt!

  • Ik zou zelf voor PDO gaan. De prepared statement werken ideaal, aangezien deze, zoals @P.Ynteme al zei het zelf al doet. Daarnaast vind ik PDO een stuk netter en overzichtelijker werken dan MySQLi, maar dat is voorkeur.


    Het grootste verschil zit hem waarschijnlijk in dat MySQLi op een gegeven moment eruit gaat, en PDO het stokje volledig overneemt.


    Zie https://code.tutsplus.com/tuto…should-you-use--net-24059 voor als je nog twijfels hebt ;)

    PHP, JAVA, C#, JAVASCRIPT, HTML(5), CSS(3) developer.
    Vragen?! Stuur me gerust een prive bericht :) !

  • Okay, hier gaan we weer :D. (hiermee bedoel ik de eeuwige PDO versus MySQLi discussie)

    Ik vroeg mij dus af, of ik dan het beste in PDO of MySQLi werk voor performantie en beveiliging

    Bij een juist gebruik zijn beide even (on)veilig. Performance is vrijwel hetzelfde voor alle MySQL drivers / API's (zie het onderdeel Recommended API).


    of is dit gewoon persoonlijke voorkeur?

    Ja, tenzij je moet voldoen aan zekere standaarden? Gaat dit ergens in geintegreerd worden, of is dit een standalone ding of maken jullie er een API van? In het laatste geval houd je zelf de controle en zou je het als dienst kunnen aanbieden zonder een letter code uit handen te geven?


    Indien ik de data die binnenkomt controleer en escape, is dit dan genoeg?

    Het adagium is nog steeds filter input, escape output. Ik hoop dan ook van harte dat je geen input escaped. Dit is slechts in uitzonderlijke, en gedocumenteerde, gevallen wenselijk. Misschien is er verwarring over wat input en wat output is. Als je USER DATA ontvangt via een formulier, querystring of zelfs uit de database (dit is nog steeds USER DATA en dus nog steeds onbetrouwbaar) kun je deze onderwerpen aan allerlei tests om te zien of deze voldoet aan een zeker formaat of bepaalde regels. Dit is het filteren van input: je controleert of deze op grond van eigen spelregels correct is voor verder gebruik. Vervolgens ga je deze USER DATA in een bepaalde context gebruiken: als output op een HTML-pagina of als DATA in een SQL string. Afhankelijk van deze context en wanneer je deze data niet kunt vertrouwen is het zaak dat je deze binnen de context onschadelijk maakt. Denk in HTML aan functies als htmlspecialchars(). Dat is het escapen van output: het onschadelijk maken van data binnen een bepaalde context. Nog eentje voor aan de muur: Never Trust User Data.


    Of zijn prepared statements echt een must?

    Prepared statements zijn slechts een middel, geen doel. Een verkeerd gebruik hiervan (eentje waarbij SQL statements worden opgebouwd door onder andere externe DATA te concateneren in de SQL-string en dan wat gegoochel met prepared statements) is nog steeds funest.


    Het grootste verschil zit hem waarschijnlijk in dat MySQLi op een gegeven moment eruit gaat, en PDO het stokje volledig overneemt.

    Dat is interessant, heb je hier ook een bron van die dit onderbouwt? Of een officiele aankondiging van de geplande end-of-life van de MySQLi driver / API? Ik denk dat de te schrijven programmacode die hier gebruik van maakt eerder zal worden vervangen / opgeschoond eerlijk gezegd. Daarnaast kun je je queries zo in je code compartimenteren dat je slechts de queries hoeft te vervangen of dat je -in het gunstigste geval- enkel de schil waarmee je met de database communiceert hoeft aan te passen en niet al je code. Hoe je dit kunt ondervangen staat verderop in dit verhaal.


    Zie code.tutsplus.com/tutorials/pd…should-you-use--net-24059 voor als je nog twijfels hebt

    Oh. Dat artikel. Uit 2012. Let ook vooral op de datum van dit soort technische artikelen, deze kunnen vrij snel hun houdbaarheid verliezen.


    Ik ga wat proberen uit te leggen over PDO die je mogelijk kan helpen bij het maken van een keuze.


    In het verleden heb ik mij verdiept in MySQLi en PDO. Ik ben ook op zoek geweest naar beweegredenen om voor PDO te kiezen (boven MySQLi als je een MySQL db gebruikt). De enige zinnige reden die uiteindelijk overeind bleef was het argument waarbij het bij de ontwikkeling van de applicatie nog niet vaststaat welk db-type je uiteindelijk gaat gebruiken. Dit is het enige echte zinnige argument wat ik kon vinden in alle discussie. De rest was meer persoonlijke voorkeur, waar het in het eerder gelinkte artikel ook sterk naar neigt. Maar goed, omgekeerd, als je wéét dat je enkel een MySQL-database gaat gebruiken, dan is het naar mijn mening gewoon veel zinniger om een driver/API te kiezen die hiervoor gemaakt is.


    De argumenten in het artikel gaan slechts gedeeltelijk, niet echt, of echt niet op (waarom PDO "beter" zou zijn) en daarvoor moet je wat dieper graven in PDO om te snappen hoe dit precies in zijn werk gaat. Allereerst, PDO zelf is slechts een handjevol klasses die het praten met databases standaardiseert. Maar hier kun je meteen al de boot ingaan qua interpretatie: het praten met de database is dan wel gestandaardiseerd, maar de SQL-taal die gesproken wordt is nog steeds DATABASE SPECIFIEK. Wat je moet begrijpen is dat PDO géén database-abstractie regelt, maar enkel fungeert als een data-access abstractie laag. Dus eigenlijk regelt PDO zelf in het geheel geen database-specifieke zaken. Dit doen de PDO drivers.


    En dat is meteen een vette adder onder het gras. Immers, omdat PDO geen database-specifieke dingen regelt is deze op voorhand dus ook niet afgestemd/geoptimaliseerd voor gebruik van een specifieke database. Zo'n standaard manier van communiceren met een database is misschien handig, maar daar zit de leercurve ook helemaal niet! Deze zit in de drivers! Tegenwoordig zullen alle standaard instellingen wel redelijk zinnig zijn, maar als je je bijvoorbeeld niet wilt verdiepen in alle PDO attributen die gemoeid zijn met een specifieke database, wat deze inhouden, en wat voor specifieke implicaties deze hebben op de werking en het gebruik (leercurve) dan is MySQLi wellicht toch wat simpeler :p. MySQLi is gebruiksklaar: deze is specifiek geschreven en geoptimaliseerd voor gebruik van MySQL-databases.


    Het artikel adverteert met "PDO ondersteunt veel meer databases (dan MySQLi)". Maar dit is vaak een non-argument in die zin dat je in de levensloop van een applicatie niet continu schakelt van database-type. Althans niet zonder te testen. Tenzij het product uit allerlei verschillende bronnen / database-typen informatie haalt, maar dan moet je des te beter nadenken over de architectuur hiervan en dan kan PDO mogelijk uitkomst bieden. Dit neemt echter niet weg dat je je zult moeten verdiepen in de werking van ALLE gebruikte PDO-drivers.


    En als je toch enkel van MySQL gebruik maakt, dan is dit "PDO ondersteunt veel meer databases" nogal nutteloos. Maar simpelweg zeggen, of hiermee een soort van onderbuikgevoel kweken, dat PDO daarom beter zou zijn is natuurlijk je reinste kwats. Natuurlijk, het is een industriestandaard (? of liever gezegd "iedereen" gebruikt het?), maakt het nog niet de beste keuze voor jouw specifieke probleem. Daarnaast, als niet is vastgelegd wat je zou moeten gebruiken heb je nog altijd zelf de keuze.


    Het artikel vind ik dus persoonlijk een soort van reclamefolder van een enthousiaste PDO-gebruiker die anderen met oneigenlijke argumenten probeert te overtuigen.


    On a side note: de "prepared statements" die PDO gebruikt is een soort van clientside prepared statements, deze maakt (tenzij je het PDO-attribuut PDO::ATTR_EMULATE_PREPARES juist instelt) geen gebruik van de native support die MySQL (op database-niveau) heeft voor prepared statements. Dit zijn twee compleet verschillende dingen! Voor de goede orde zou je de waarden van alle relevante attributen af moeten lopen en/of expliciet in moeten stellen om je ervan te vergewissen dat alles naar behoren werkt. En natuurlijk moeten weten wat deze alle betekenen en wat voor implicaties dat heeft (leercurve).


    On another side note: de laatste keer dat ik in PDO prepared statements gebruikte negeerde deze mijn typehints compleet. Als ik de MySQL log mocht geloven behandelde 'ie alles als string, ook al gaf ik aan dat dit getallen / reals / floats / whatever betrof.


    Okay, nog wat korte notities over MySQLi. Prepared statement zoals MySQLi deze aanbiedt: niet gebruiken, is compleet ruk. Het opbouwen, aanroepen en uitlezen van queries en -resultaten wordt ontzettend wollig en bovendien compleet onleesbaar. Wat ik persoonlijk zou doen is voor MySQLi zelf een data-access abstractie laag (DAAL) te schrijven of ergens vandaan te plukken. Dit om je database-oplossing niet compleet te hardcoden en hiermee ondervang je ook het probleem dat als er iets in MySQL-land verandert dat je, met enig geluk, deze wijzigingen kunt ondervangen door je DAAL aan te passen en geen dingen in je code hoeft te searchen en te replacen. Het op deze manier rechtstreeks hardcoden van je MySQLi-functies of -methoden in je code, dat zou echt een heel erg slecht idee zijn.


    Dus, ff wat leidraden:
    - ligt het vast wat je moet gebruiken, ben je klaar (en dan hoop ik dat de personen die dit besluit namen niet het genoemde artikel als leidraad gebruiken, maar toch wat beter geinformeerd zijn)
    - gebruik je enkel MySQL, gebruik MySQLi, maak / download een DAAL, houd database-aanroep-specifieke code buiten code en in je DAAL; ik zou dan gaan voor de OOP aanpak met het handmatig escapen van alle DATA binnen de SQL; dit legt wat verantwoordelijkheid bij je programmeurs, maar als je hier geen afspraken over kunt maken, zou ik de integriteit van de rest van je code ook niet vertrouwen
    - gebruik je iets anders of verschillende dingen: denk eerst nog eens goed na over hoe je dit aan gaat pakken


    Meer vragen / opmerkingen: ben benieuwd.


    /rant

  • Nog een toevoeging, kon deze niet in vorige bericht kwijt (10.000 karakters was te krap :p):
    PS het feit dat in het artikel compleet voorbij wordt gegaan gaat aan het expliciet instellen van een character encoding geeft voor mij al aan dat het allemaal nogal oppervlakkig is. Dat is namelijk een bron van zeer veel ellende die nog altijd zwaar onderschat wordt. Vaak omdat mensen (of nog erger, programmeurs) niet van het bestaan weten.


    Dit artikel lijkt mij in zekere zin nog steeds een beter artikel dat zich bezighoudt met fundamenten, en niet zozeer met specifieke oplossingen. Dit artikel is vandaag de dag nog zeer relevant, en wordt eigenlijk steeds relevanter. Voordat dit als een soort van gospel ingeprent is bij alle programmeurs zouden ze eigenlijk in het geheel niet met databases mogen werken.

Participate now!

Heb je nog geen account? Registreer je nu en word deel van onze community!