dinsdag 10 september 2013

Van MySQL naar MySQLi

Wie nu nog werkt met de PHP-extensie mysql voor MySQL, moet binnenkort overstappen op een alternatief. De standaardextensie mysql wordt vanaf PHP 5.5.0 aangemerkt als deprecated en kan uit toekomstige versies van PHP verdwijnen. Een goed alternatief is de verbeterde versie mysqli, met de i van improved. De nieuwere PHP-extensie mysqli lijkt het meest op de verouderde extensie mysql en maakt overstappen gemakkelijk.

Technische verschillen tussen mysql en mysqli

De standaardfuncties van PHP voor MySQL voldeden prima voor de meeste databasegestuurde webapplicaties. Toch waren ze voor verbetering vatbaar. Op veel webservers met PHP en MySQL kun je al langer een bundel verbeterde databasefuncties gebruiken die luistert naar de welluidende naam MySQL Improved en afgekort MySQLi of mysqli.

De verbeterde PHP-extensie mysqli heeft enkele voordelen. Het grootste technische verschil is dat mysqli nieuwe functionaliteit ondersteunt die alleen beschikbaar is in MySQL 4.1 en hoger. Moderne versies van MySQL hebben meer geavanceerde opties voor databaseverbindingen, zijn beter beveiligd en kunnen prepared statements uitvoeren, databaseopdrachten waarbij je bijvoorbeeld een query strikt kunt scheiden van de data waarmee de query werkt.

Die nieuwe functionaliteit heb je lang niet altijd nodig. Het belangrijkste praktische verschil is echter nog een goede reden om toch mysqli te gebruiken: mysqli is meetbaar sneller, zelfs als je uitsluitend standaardmogelijkheden van MySQL gebruikt.

Hoewel mysqli achterwaarts compatibel is met de standaardextensie mysql, werkt mysqli net iets anders. Hierna vind je een overzicht van de belangrijkste verschillen.

De i van improved

Voor elke functie uit de verouderde extensie mysql voor MySQL heeft mysqli een gelijknamige tegenhanger met een extra i van improved. Bijvoorbeeld de standaardfunctie mysql_error() voor het melden van fouten heet mysqli_error() bij de extensie mysqli.

Voor andere bouwstenen van PHP geldt hetzelfde. Voor het opvragen van een associatieve array kun je bijvoorbeeld mysql_fetch_array() met de constante MYSQL_ASSOC vervangen door mysqli_fetch_array() met de constante MYSQLI_ASSOC met een extra kleine letter i in de functienaam en een extra hoofdletter I in de constantennaam. Directives in het PHP-configuratiebestand php.ini zoals mysql.default_host voor de standaardextensie mysql heten mysqli.default_host voor de extensie mysqli.

Sommige PHP-gebruikers hebben mysqli links laten liggen omdat ze dachten dat mysqli alleen geschikt is voor objectgeoriënteerd programmeren (OOP). Dat is een misverstand. De extensie mysqli is geschikt voor objectgeoriënteerd PHP én voor procedureel PHP. In de PHP Manual vind je bij alle functies van mysqli steeds zowel objectgeoriënteerde als procedurele voorbeelden.

Databaseverbindingen en de link identifier

Het grootste technische verschil tussen mysql en mysqli is de wijze waarop databaseverbindingen worden afgehandeld. Bij de standaardextensie wordt automatisch de laatst geopende databaseverbinding gebruikt als je zelf geen andere databaseverbinding opgeeft. In de standaardfuncties voor MySQL is de resource voor de databaseverbinding daarom een niet-vereiste parameter.

De verbeterde extensie mysqli is strenger. Hierbij moet je altijd opgeven welke databaseverbinding je wilt gebruiken, wat in principe het gebruik van systeembronnen verbetert. Doordat de databaseverbinding een vereiste parameter is geworden, is helaas ook de volgorde van parameters in veel functies veranderd. Vereiste parameters staan in PHP-functies namelijk altijd voor niet-vereiste parameters.

Bij de standaardfunctie mysql_query() voor het uitvoeren van een query is de databaseverbinding bijvoorbeeld de tweede, niet-vereiste parameter $link_identifier:

resource mysql_query ( string $query [, resource $link_identifier = NULL ] )

Bij de gelijkwaardige functie mysqli_query() van mysqli is de databaseverbinding echter de eerste, vereiste parameter $link geworden:

mixed mysqli_query ( mysqli $link , string $query [, int $resultmode = MYSQLI_STORE_RESULT ] )

Waarschuwing! Doordat de volgorde van parameters is veranderd, kun je het prefix mysql_ in functienamen helaas niet zomaar met ‘zoeken en vervangen’ veranderen in mysqli_. Je moet bij elke functie controleren of je de juiste vereiste parameters opgeeft én of die parameters in de juiste volgorde staan.

Andere verbeteringen

Een lichtpuntje is dat in mysqli enkele tientallen fouten uit de standaardextensie mysql zijn verbeterd. Een duidelijk voorbeeld is het openen van databaseverbindingen. Bij de standaardextensie mysql moet je altijd eerst een verbinding met de databaseserver openen met mysql_connect() en vervolgens een database op de server selecteren met mysql_select_db():

$link mysql_connect('localhost''root''********');
mysql_select_db('test');

Die dubbele handeling is vrijwel altijd overbodig, aangezien je een databaseverbinding meestal opent om vervolgens aan de slag te gaan met een bepaalde database. In mysqli_connect() kun je de nieuwe, vierde parameter $dbname gebruiken voor het doorgeven van de databasenaam:

$link mysqli_connect('localhost''root''********''test');

Wil je PHP-script met mysql herschrijven naar mysqli, dan kun je de functie mysql_select_db() ook vervangen door mysqli_select_db(). Het enige verschil wordt dan dat je de geopende databaseverbinding, in dit voorbeeld $link, moet doorgeven in de eerste parameter:

$link mysqli_connect('localhost''root''********');
mysqli_select_db($link'test');

Besluit

Als je nu nog procedureel PHP-script met mysql hebt, is de overstap naar mysqli klein. Je hoeft eigenlijk maar twee dingen te doen: op de juiste plaatsen een i of I toevoegen en de volgorde van parameters in functies controleren. In ruil daarvoor krijg je een PHP-applicatie die weer bij de tijd, veiliger én sneller is. Kleine moeite, groot plezier.

Deze blogpost is een bewerking van een paragraaf uit mijn boek Het beste van PHP en MySQL, dat in 2009 is verschenen bij Pearson. Het beste van PHP en MySQL is onder andere verkrijgbaar als e-book bij bol.com.

Geen opmerkingen:

Een reactie posten