Spring naar hoofdtekst

Nostalgie in PHP en MySQL

Geplaatst op door ,
Laatste aanpassing op .

Inleiding

Laatst kwam ik tussen oude back-ups een SQL-bestand tegen van een zelfgebouwd forum uit 2010. Ook de code was bewaard gebleven en stond zelfs in één van mijn lokale Git-repositories. Hoe leuk zou het zijn om al die oude berichten nog eens te kunnen lezen? Om van de hilarische code-kwaliteit nog maar te zwijgen…

Setup

Het inlezen van de database was redelijk eenvoudig: een source setup.sql in de MySQL-console en het was geregeld. Het op gang helpen van de PHP-code zou behoorlijk wat meer tijd in beslag nemen. In eerste instantie verscheen er een blanco pagina bij het oproepen van index.php - een slecht teken.

Diagnose

Aldus ging ik met echo en var_dump op zoek naar de plek waar PHP de bocht uit vloog. Ik kwam terecht bij een aanroep van mysql_query(), een veelgebruikte functie om een aanvraag op de database uit te voeren. Maar, ik heb toch een MySQL-server draaien, en de juiste gegevens in de configuratie ingesteld?

Jawel, maar sinds PHP 5.5 zijn de oude mysql_-functies afgeschreven en vervangen door de modernere, snellere en veiligere mysqli_-varianten. Als ik dit forum op mijn huidige (PHP7) machine wilde draaien, moest ik een alternatief zoeken.

Aanpak

Door de gehele broncode lagen honderden aanroepen verspreid - ik had geen zin om alle code door te spitten en overal aanpassingen te maken. Als vanzelf kwam de gedachte om wrapper-functies te schrijven. Als PHP de functies niet meer aan boord heeft, dan kan ik ze toch zelf opnieuw definiëren? En dan achter de schermen de nieuwe functies aanroepen.

Maar hoe vind ik alle verschillende functies die ik moet 'vervangen'? grep to the rescue! Met onderstaande one-liner vond ik alle aan MySQL geliëerde commando's in de broncode:

$ grep -rihIPo 'mysql_[^(]+' * | sort | uniq
mysql_affected_rows
mysql_errno
mysql_fetch_array
mysql_num_rows
mysql_pconnect
mysql_query
mysql_real_escape_string
mysql_result
mysql_select_db
mysql_set_charset

grep zoekt in tekstbestanden naar tekenreeksen of patronen. In dit geval recursief in alle mappen (-r) en bestanden (*) met Perl-compatibele regular expressies (-P). Verder wordt geen verschil gemaakt tussen hoofd- en kleine letters (-i), worden binaire bestanden genegeerd (-I) en geen bestandsnamen in de output opgenomen (-h). Met -o geeft grep alléén het gematchte stukje terug.

Dan volgt de magie van een eenvoudige reguliere expressie. Hier wordt gezocht naar de tekst mysql_, gevolgd door alles wat geen openende ronde haak is ([^(]+). De uitvoer wordt gesorteerd en gefilterd op duplicaten. Uiteindelijk bleven de getoonde funcies over, waarvoor ik een wrapper moest schrijven.

Wrappers

Gelukkig gebruikte ik in die tijd wel al het systeem van één centrale include. Daarin werd de databaseverbinding gelegd en alle globale functies gedefiniëerd. Ik maakte de volgende aanpassing:

<?php
$db = mysqli_connect(
    $config['host'], $config['user'], $config['password'], $config['database']
);
mysqli_set_charset($db, 'utf8');

function mysql_affected_rows(){
    global $db;
    return mysqli_affected_rows($db);
}
function mysql_errno(){
    global $db;
    return mysqli_errno($db);
}
function mysql_fetch_array($q){
    return mysqli_fetch_array($q);
}
function mysql_num_rows($q){
    return mysqli_num_rows($q);
}
function mysql_query($q){
    global $db;
    return mysqli_query($db, $q);
}
function mysql_real_escape_string($q){
    global $db;
    return mysqli_real_escape_string($db, $q);
}
function mysql_result($q, $o){
    mysqli_data_seek($q, $o);
    $row = $q->fetch_row();
    return $row[0];
}

Inhoudsopgave

Klik op één van de onderstaande categorieën om de lijst met artikelen te filteren.