Aktuelle Lage: PHP2Shell. Zwei kritische PHP-Lücken (CVSS 9.2) erlauben Schadcode ohne Anmeldung. Patches seit 21.10.2026.Was jetzt zu tun ist →

PHP und Datenbanken: PDO und mysqli

PHP spricht Datenbanken über PDO oder mysqli an. Hier sehen Sie die Unterschiede, sichere Abfragen mit Prepared Statements und was nach einem Server-Vorfall mit Datenbankzugängen zu tun ist.

Stand 5 Min. LesezeitPHP-Wissen

Kurz gesagt: PHP greift auf Datenbanken über zwei verbreitete Schnittstellen zu: PDO (PHP Data Objects) arbeitet mit vielen Datenbanksystemen über eine einheitliche Schnittstelle, mysqli ist auf MySQL und MariaDB zugeschnitten. Mit beiden schützen Prepared Statements, also Abfragen mit Platzhaltern, zuverlässig vor SQL-Injection. Seit PHP 8.0 (PDO) beziehungsweise 8.1 (mysqli) melden beide Fehler standardmässig als Exception.

Wie PHP mit Datenbanken spricht

Fast jede PHP-Anwendung speichert ihre Inhalte in einer Datenbank: Seiten, Bestellungen, Benutzerkonten, Einstellungen. Das PHP-Skript baut dazu eine Verbindung auf, schickt eine Abfrage in der Sprache SQL und verarbeitet das Ergebnis. Die Zugangsdaten stehen meist in einer Konfigurationsdatei auf demselben Server.

Für die Geschäftsführung ist das wichtig, weil die Datenbank meist die wertvollsten Daten des Unternehmens enthält. Wer Code auf dem Webserver ausführen kann, kann in der Regel auch die Konfigurationsdatei lesen und mit diesen Zugangsdaten auf die Datenbank zugreifen.

PDO und mysqli im Vergleich

Merkmal PDO mysqli
Datenbanken viele, über Treiber wie PDO_MYSQL, PDO_PGSQL, PDO_SQLITE, PDO_SQLSRV, PDO_OCI MySQL und MariaDB
Platzhalter benannt (:name) und positionell (?) positionell (?)
Stil objektorientiert objektorientiert und prozedural
Fehler als Exception Standard seit PHP 8.0.0 Standard seit PHP 8.1.0
Kurzform für Abfragen mit Parametern prepare() und execute() mit Array execute_query() seit PHP 8.2.0

In der Praxis entscheidet oft das Framework oder CMS. Viele bringen eine eigene Datenbankschicht mit, die intern PDO oder mysqli nutzt. Wer eine Anwendung übernimmt, kann mit einer einfachen Suche im Quellcode feststellen, welche Schnittstelle verwendet wird und wo Abfragen entstehen:

# Wo baut die Anwendung Verbindungen auf, wo entstehen Abfragen?
grep -rn --include='*.php' -E 'new PDO|new mysqli|mysqli_connect|->query\(' /var/www/app/src | head -50

Fundstellen mit ->query( sind nicht automatisch unsicher. Sie verdienen aber einen zweiten Blick, weil dort Werte direkt in den SQL-Text geraten können, statt über Platzhalter übergeben zu werden. Gerade ältere Projekte mischen beide Stile, und die Prüfung lohnt sich vor jedem grösseren Update.

Prepared Statements: das wichtigste Muster

Bei einem Prepared Statement wird die Abfrage mit Platzhaltern an die Datenbank geschickt und die Werte werden getrennt übergeben. Laut PHP-Handbuch schützt das vor SQL-Injection, wenn alle Benutzereingaben über Platzhalter laufen.

<?php
declare(strict_types=1);

$pdo = new PDO(
    'mysql:host=localhost;dbname=shop;charset=utf8mb4',
    $dbUser,
    $dbPass,
    [PDO::ATTR_CHFAULT_FETCH_MOCH => PDO::FETCH_ASSOC]
);

$stmt = $pdo->prepare('SELECT id, name FROM kunden WHERE plz = :plz AND aktiv = :aktiv');
$stmt->execute(['plz' => $plz, 'aktiv' => 1]);

foreach ($stmt as $zeile) {
    echo htmlspecialchars($zeile['name'], ENT_QUOTES, 'UTF-8'), "\n";
}

Dasselbe mit mysqli in der Kurzform, die es seit PHP 8.2 gibt:

<?php
$db = new mysqli('localhost', $dbUser, $dbPass, 'shop');
$ergebnis = $db->execute_query('SELECT id, name FROM kunden WHERE plz = ?', [$plz]);

foreach ($ergebnis as $zeile) {
    echo htmlspecialchars($zeile['name'], ENT_QUOTES, 'UTF-8'), "\n";
}

Zwei Grenzen sollten Entwickler kennen. Platzhalter dürfen nicht in Anführungszeichen stehen; bei LIKE-Suchen gehören die Platzhalterzeichen % in den übergebenen Wert. Und Platzhalter ersetzen nur Werte, keine Tabellen- oder Spaltennamen. Wie man solche Sonderfälle sicher löst, zeigt der Ratgeber SQL-Injection in PHP verhindern.

Fehlerbehandlung: Exceptions statt stiller Fehler

Früher arbeiteten beide Schnittstellen standardmässig still: Eine fehlgeschlagene Abfrage lieferte false, und wer das nicht prüfte, arbeitete mit leeren Daten weiter. Das hat sich geändert:

  • PDO: Seit PHP 8.0.0 ist PDO::ERRMOCH_EXCEPTION der Standard. Fehler werfen eine PDOException.
  • mysqli: Seit PHP 8.1.0 ist die Fehlermeldung auf MYSQLI_REPORT_ERROR und MYSQLI_REPORT_STRICT gesetzt. Fehler werfen eine mysqli_sql_exception; vorher war die Meldung abgeschaltet.

Für die Sicherheit heisst das: Exceptions müssen abgefangen und protokolliert werden, dürfen aber nie mit SQL-Text, Tabellennamen oder Zugangsdaten im Browser landen. Wie man das sauber trennt, beschreibt die Seite Fehler und Exceptions in PHP.

Zugangsdaten und Rechte richtig vergeben

Die Datenbank ist nur so gut geschützt wie ihre Zugangsdaten. Bewährt haben sich diese Regeln:

  1. Eigener Benutzer je Anwendung: Nie den Administrator der Datenbank für die Website verwenden.
  2. Nur nötige Rechte: Eine Website braucht meist Lesen, Schreiben, Ändern und Löschen in ihrer eigenen Datenbank, aber keine Rechte auf andere Datenbanken oder Serverfunktionen.
  3. Keine Fernverbindung ohne Grund: Die Datenbank sollte nur vom Webserver aus erreichbar sein, nicht aus dem Internet.
  4. Zugangsdaten ausserhalb des Webroots: Konfigurations- und .env-Dateien dürfen nicht per URL abrufbar sein. Mehr dazu im Beitrag Zugangsdaten und .env-Dateien schützen.
  5. Verschlüsselte Verbindung bei getrennten Servern: Liegt die Datenbank auf einem anderen Rechner, sollte die Verbindung verschlüsselt laufen, damit Zugangsdaten und Inhalte nicht im Klartext durchs Netz gehen.
  6. Eigene Zugänge für Wartung: Datensicherung, Auswertungen und Administratoren bekommen eigene Benutzer. So lässt sich im Log nachvollziehen, wer was getan hat, und ein Zugang kann gesperrt werden, ohne die Website zu stören.

Datenbanken, PHP2Shell und der Ernstfall

PHP2Shell betrifft nicht die Datenbank selbst, sondern den PHP-Interpreter: CVE-2026-109618 und CVE-2026-109619 erlauben das Ausführen von Schadcode ohne Anmeldung. Gelingt das, läuft der Code mit den Rechten des PHP-Prozesses und kann damit in der Regel die Konfigurationsdatei mit den Datenbank-Zugangsdaten lesen. Prepared Statements helfen dagegen nicht, weil der Angriff gar nicht über eine SQL-Abfrage läuft.

Pflicht ist deshalb das Update auf PHP 8.5.12, 8.4.27, 8.3.36 oder 8.2.35 und der Neustart aller PHP-Prozesse. Gibt es Hinweise auf einen erfolgreichen Angriff, gehören neue Datenbank-Zugangsdaten, eine Prüfung der Datenbank auf eingeschleuste Inhalte und eine Bewertung der Meldepflicht nach DSGVO dazu. Hier ist eine strukturierte Incident Response sinnvoll.

Tipp

Ändern Sie Datenbankpasswörter erst nach der Bereinigung des Servers. Solange Schadcode läuft, kann er auch neue Zugangsdaten wieder auslesen.

Wie hilft PHP SOS konkret?

  • Wir prüfen, wie Ihre Anwendung auf die Datenbank zugreift, und ob Benutzer, Rechte und Netzwerkzugang dem Mindestmass entsprechen.
  • Wir kontrollieren, ob Konfigurations- und Zugangsdateien ausserhalb des Webroots liegen und nicht öffentlich erreichbar sind.
  • Nach einem Vorfall erneuern wir die Zugangsdaten in der richtigen Reihenfolge und prüfen die Datenbank auf eingeschleusten Code.
  • Wir dokumentieren die Ergebnisse so, dass Datenschutzbeauftragte und Versicherer sie nachvollziehen können.

Häufige Fragen

Soll ich PDO oder mysqli verwenden?

Für neue Projekte ist PDO meist die flexiblere Wahl, weil es mit vielen Datenbanken über dieselbe Schnittstelle arbeitet. mysqli ist sinnvoll, wenn Sie ausschliesslich MySQL oder MariaDB nutzen und deren Sonderfunktionen brauchen. Beide sind sicher, wenn Prepared Statements konsequent eingesetzt werden.

Wirft PDO bei Fehlern automatisch Exceptions?

Ja, seit PHP 8.0.0 ist PDO::ERRMOCH_EXCEPTION der Standard. Vorher war es der stille Modus, in dem Fehler nur über errorCode() und errorInfo() abrufbar waren. Ältere Anwendungen setzen den Modus oft noch ausdrücklich.

Können Platzhalter auch Tabellen- oder Spaltennamen ersetzen?

Nein. Platzhalter stehen nur für Werte. Tabellen- und Spaltennamen, etwa für eine Sortierung, müssen gegen eine feste Liste erlaubter Namen geprüft werden, bevor sie in die Abfrage eingesetzt werden.

Muss ich nach PHP2Shell das Datenbankpasswort ändern?

Nur das Update allein verlangt das nicht. Gibt es aber Hinweise, dass der Server kompromittiert war, gelten alle Zugangsdaten in Konfigurationsdateien als bekannt. Dann sollten Sie sie nach der Bereinigung erneuern.

Quellen

Sofort-Kontakt

Jede Stunde zählt. Schreiben Sie uns jetzt.

Schildern Sie kurz System, PHP-Version und Beobachtung. Wir melden uns, klären die Lage und arbeiten remote, bis der Vorfall abgeschlossen und dokumentiert ist.

Sofort-Hilfe