MySQLDumper und Legacy-PHP unter PHP 7/8 zum Laufen bringen
Du hast deinen Server auf PHP 7 oder PHP 8 aktualisiert, und plötzlich wirft MySQLDumper nur noch Fehlermeldungen? Das liegt daran, dass die alte mysql_*-Erweiterung seit PHP 7.0 komplett entfernt wurde. Keine Deprecation-Warnung mehr, kein Fallback — einfach weg. Das betrifft nicht nur MySQLDumper, sondern jedes Legacy-PHP-Tool, das noch die klassischen mysql_*-Funktionen verwendet.
Das Problem: mysql_* vs. mysqli_*
Die alte MySQL-Erweiterung (mysql_*) war über ein Jahrzehnt der Standard für PHP-Datenbankzugriffe. Ab PHP 5.5 wurde sie als deprecated markiert, ab PHP 7.0 ist sie entfernt. Die Nachfolgerin heißt mysqli_* (MySQL Improved) und bietet mehr Funktionen, bessere Sicherheit und Support für Prepared Statements.
Typische Fehlermeldungen nach dem PHP-Upgrade:
Fatal error: Uncaught Error: Call to undefined function mysql_connect()
Fatal error: Uncaught Error: Call to undefined function mysql_query()
Fatal error: Uncaught Error: Call to undefined function mysql_real_escape_string()
Die Lösung: Alle mysql_*-Aufrufe durch ihre mysqli_*-Pendants ersetzen. Klingt einfach — hat aber ein paar Fallstricke.
Die wichtigsten Funktions-Umbenennungen
Hier die häufigsten Funktionen und ihre modernen Entsprechungen:
| Alt (mysql_*) | Neu (mysqli_*) | Hinweis |
|---|---|---|
mysql_connect() |
mysqli_connect() |
Parameter-Reihenfolge gleich |
mysql_select_db($db) |
mysqli_select_db($link, $db) |
Connection-Parameter kommt zuerst |
mysql_query($sql) |
mysqli_query($link, $sql) |
Connection-Parameter erforderlich |
mysql_fetch_array($result) |
mysqli_fetch_array($result) |
Kompatibel |
mysql_fetch_assoc($result) |
mysqli_fetch_assoc($result) |
Kompatibel |
mysql_fetch_row($result) |
mysqli_fetch_row($result) |
Kompatibel |
mysql_num_rows($result) |
mysqli_num_rows($result) |
Kompatibel |
mysql_affected_rows() |
mysqli_affected_rows($link) |
Connection-Parameter erforderlich |
mysql_real_escape_string($str) |
mysqli_real_escape_string($link, $str) |
Connection-Parameter erforderlich |
mysql_error() |
mysqli_error($link) |
Connection-Parameter erforderlich |
mysql_close() |
mysqli_close($link) |
Connection-Parameter erforderlich |
mysql_insert_id() |
mysqli_insert_id($link) |
Connection-Parameter erforderlich |
Der größte Unterschied: Bei mysqli_* musst du fast überall die Datenbankverbindung als ersten Parameter mitgeben. Bei den alten mysql_*-Funktionen war das optional — PHP hat einfach die zuletzt geöffnete Verbindung genommen.
Code-Beispiel: Vorher und Nachher
Alter Code (PHP 5.x, funktioniert nicht mehr):
// Verbindung herstellen
$conn = mysql_connect('localhost', 'root', 'passwort');
mysql_select_db('meine_datenbank');
// Abfrage
$result = mysql_query("SELECT * FROM users WHERE active = 1");
while ($row = mysql_fetch_assoc($result)) {
echo $row['username'] . "\n";
}
// Escaping
$name = mysql_real_escape_string($_POST['name']);
$sql = "INSERT INTO users (name) VALUES ('$name')";
mysql_query($sql);
mysql_close($conn);
Neuer Code (PHP 7/8, mysqli):
// Verbindung herstellen
$conn = mysqli_connect('localhost', 'root', 'passwort', 'meine_datenbank');
if (!$conn) {
die('Verbindung fehlgeschlagen: ' . mysqli_connect_error());
}
// Abfrage
$result = mysqli_query($conn, "SELECT * FROM users WHERE active = 1");
while ($row = mysqli_fetch_assoc($result)) {
echo $row['username'] . "\n";
}
// Escaping (besser: Prepared Statements verwenden!)
$name = mysqli_real_escape_string($conn, $_POST['name']);
$sql = "INSERT INTO users (name) VALUES ('$name')";
mysqli_query($conn, $sql);
mysqli_close($conn);
Das MySQLConverterTool
Oracle hat auf GitHub das MySQLConverterTool bereitgestellt, das die Konvertierung automatisch durchführt. Es ist ein PHP-Skript, das deinen Quellcode scannt und mysql_*-Aufrufe durch mysqli_* ersetzt.
# Repository klonen
git clone https://github.com/niclasleonbock/MySQLConverterTool.git
# Oder das Original von Oracle (falls verfügbar)
git clone https://github.com/mysql/mysql-converter-tool.git
Das Tool macht einen guten ersten Durchlauf, aber du musst danach manuell nacharbeiten. Es gibt Fälle, die das Tool nicht korrekt konvertiert.
Manuelle Fixes: Die häufigsten Stolpersteine
1. Die db_escape-Funktion
Viele Legacy-Projekte — darunter auch MySQLDumper — haben eigene Wrapper-Funktionen für das Escaping. Die müssen ebenfalls angepasst werden:
// Alt:
function db_escape($string) {
return mysql_real_escape_string($string);
}
// Neu — braucht die Connection:
function db_escape($string, $conn) {
return mysqli_real_escape_string($conn, $string);
}
// Oder als globale Variable:
function db_escape($string) {
global $dbconn;
return mysqli_real_escape_string($dbconn, $string);
}
2. Implizite Verbindung entfernen
Der alte Code verlässt sich oft darauf, dass PHP die letzte Verbindung automatisch verwendet. Bei mysqli_* musst du die Verbindung explizit übergeben. Suche im Code nach allen Stellen, die mysql_query() ohne Verbindungsparameter aufrufen, und ergänze den $conn-Parameter.
3. mysql_result() gibt es nicht mehr
Die Funktion mysql_result() hat kein direktes mysqli_*-Pendant. Du musst sie umschreiben:
// Alt:
$value = mysql_result($result, 0, 'name');
// Neu:
$row = mysqli_fetch_assoc($result);
$value = $row['name'];
PHP-Migration Checkliste: Weitere Fallstricke ab PHP 7/8
Neben mysql_* gibt es weitere Änderungen, die bei der Migration von altem PHP-Code zu Problemen führen:
PHP 7.0+
ereg()underegi()entfernt — ersetzen durchpreg_match()split()entfernt — ersetzen durchexplode()oderpreg_split()- Konstruktor-Methoden mit Klassennamen (
function ClassName()) deprecated — verwende__construct() - Strikte Typprüfung:
==verhält sich bei String-Vergleichen anders
PHP 8.0+
each()entfernt — ersetzen durchforeachcreate_function()entfernt — ersetzen durch anonyme Funktionen- Named Arguments und Union Types — kein Problem bei altem Code, aber gut zu wissen
- Match-Expressions als Alternative zu Switch
- Wichtig: Viele Funktionen geben bei Fehlern jetzt
TypeErrorstattfalsezurück
PHP 8.1+
FILTER_SANITIZE_STRINGdeprecated- Implizite Konvertierungen von Float zu Int werfen Deprecation-Notices
$GLOBALSist nicht mehr beschreibbar als Variable
MySQLDumper konkret auf PHP 8 bringen
Für MySQLDumper selbst sieht der Prozess so aus:
- Alle PHP-Dateien durchsuchen:
grep -rn "mysql_" *.php - Ersetze
mysql_connectdurchmysqli_connectmit dem vierten Parameter (Datenbankname) - Ersetze alle
mysql_query($sql)durchmysqli_query($conn, $sql) - Ersetze
mysql_real_escape_stringdurchmysqli_real_escape_stringmit Connection - Ersetze
mysql_resultdurchmysqli_fetch_*-Konstrukte - Teste jede Funktion einzeln: Backup erstellen, Backup wiederherstellen, Tabellenliste, Datenbank-Info
# Alle betroffenen Dateien finden
grep -rln "mysql_connect\|mysql_query\|mysql_fetch\|mysql_real_escape" /pfad/zu/mysqldumper/
# Schnelle Ersetzung mit sed (vorher Backup machen!)
sed -i 's/mysql_query(/mysqli_query($GLOBALS["dbconn"], /g' datei.php
sed -i 's/mysql_fetch_assoc(/mysqli_fetch_assoc(/g' datei.php
Achtung: Die sed-Methode ist nur der erste Schritt. Du musst danach alle Dateien manuell prüfen, besonders Stellen mit mysql_real_escape_string und mysql_select_db.
Alternative: Polyfill-Lösung (Notlösung)
Falls du keine Zeit für die vollständige Migration hast, gibt es eine Notlösung: einen Polyfill, der die alten mysql_*-Funktionen als Wrapper um mysqli_* nachbildet. Das ist keine dauerhafte Lösung, kann aber kurzfristig helfen:
// mysql_polyfill.php — am Anfang deiner Anwendung einbinden
if (!function_exists('mysql_connect')) {
function mysql_connect($server, $user, $password) {
global $__mysql_polyfill_conn;
$__mysql_polyfill_conn = mysqli_connect($server, $user, $password);
return $__mysql_polyfill_conn;
}
function mysql_select_db($database) {
global $__mysql_polyfill_conn;
return mysqli_select_db($__mysql_polyfill_conn, $database);
}
function mysql_query($query) {
global $__mysql_polyfill_conn;
return mysqli_query($__mysql_polyfill_conn, $query);
}
// ... weitere Funktionen analog
}
Fazit
Die Migration von mysql_* auf mysqli_* ist keine Raketenwissenschaft, aber sie erfordert Sorgfalt. Besonders bei gewachsenen Projekten wie MySQLDumper, wo die Datenbankverbindung implizit überall genutzt wird, musst du jede Datei einzeln prüfen. Das MySQLConverterTool nimmt dir die Fleißarbeit ab, aber die manuellen Fixes — vor allem bei Wrapper-Funktionen und mysql_result() — musst du selbst machen.
Falls du dabei auf Timeout-Probleme stößt, hilft dir der Artikel PHP-Timeout bei großen Datenbanken weiter.