====== Zugriff auf Datenbanken mit PHP Data Objects (PDO) ======
===== Verbindung aufbauen =====
Eine Verbindung zur Datenbank kann wie folgt aufgebaut werden:
$pdo = new PDO('mysql:host=localhost;dbname=test', 'username', 'password');
===== Einfache Abfragen =====
Nachdem eine Verbindung zur Datenbank hergestellt wurde, können SQL Statements wie folgt ausgeführt werden:
{{ auswahl_148.png|}}
$sql = "SELECT vorname, name FROM doktoren";
$query_rows = $pdo->query($sql); // liefert ein assoziatives array zurück. keys sind die feldnamen.
foreach ($query_rows as $row) {
echo $row['vorname']." ".$row['name']."
";
}
----
{{:aufgabe.png?nolink |}}
=== (A1) ===
Importiere die {{ schule500_sus_keys.zip |Tabellen der Schuldatenbank}} in deine Übungsdatenbank.
Frage die folgenden Infos in deinem PHP Skript ab und gib sie wenn sinnvoll in einer HTML-Tabelle aus:
* Erstelle eine Klassenliste der 7a
* Erstelle eine Liste aller Schüler, die Salvador Dali als Betreuer haben.
* Wieviele Schüler befinden sich in der Jahrgangsstufe 10?
===== Dynamische Abfragen =====
Mit über Formulare kann man nun auch Eingaben des Benutzers in Abfragen einbauen, auf diese Weise werden die Abfragen dynamisch.
Grundregel der Webentwicklung: Vetraue keinem Datum, das dir ein Benutzer gibt. **Auf keinen Fall sollte man in einem produktiven System Benutzereingaben direkt in SQL Statements übernehmen.**((https://www.ionos.de/digitalguide/server/sicherheit/sql-injection-grundlagen-und-schutzmassnahmen/))
Eine **schlechte Idee** ist es also, das naheliegende zu tun:
// id wird in einem Formular vom Benutzer erfragt
if(isset($_POST['id'])) {
$id = $_POST['id'];
} else {
die(" Es muss eine Datensatz ID angegeben werden!");
}
echo "Datensatz mit der ID $id:
";
$sql = "SELECT * FROM schueler WHERE id = $id";
$rows = $pdo->query($sql) ;
foreach ($rows as $row) {
echo $row['id'] . " " . $row['vorname']." ".$row['nachname']."
";
}
Dies funktioniert zwar, ist aber anfällig für sogenannte SQL Injections. Ein Angreifer kann über den POST-Parameter die SQL-Abfrage manipulieren und weiteren SQL-Code einschleusen. Im schlimmsten Fall werden dadurch sensible Daten ausgegeben, Tabelle verändert oder gar ganze Tabellen gelöscht.
Gibt der Anwender nämlich ins Formularfeld beispielsweise folgendes ein:
''1 OR id > 1''
Werden alle Datensätze ausgegeben, denn an die Datenbank wird die Abfrage ''SELECT * FROM schueler WHERE id = OR id > 1'' geschickt.
{{ :faecher:informatik:oberstufe:datenbanken:projekt:dbphp:phppdo:exploits_of_a_mom.png |}}
(Quelle: https://xkcd.com/327/, Lizenz [[http://creativecommons.org/licenses/by-nc/2.5/|Creative Commons Attribution-NonCommercial 2.5 License]].
===== Prepared Statements =====
Um SQL-Injections zu unterbinden, sollte man prepared Statements verwenden. In dem Moment, in dem ihr Daten von Benutzern an die Datenbank übergebt, solltet ihr stets auf prepared Statements zurückgreifen.
// id wird in einem Formular vom Benutzer erfragt
if(isset($_POST['id'])) {
$id = $_POST['id'];
} else {
die(" Es muss eine Datensatz ID angegeben werden!");
}
echo "Datensatz mit der ID $id:
";
$statement = $pdo->prepare("SELECT * FROM schueler WHERE id = ?");
$statement->execute(array($id));
foreach ($row = $statement->fetch())) {
echo $row['id'] . " " . $row['vorname']." ".$row['nachname']."
";
}
----
{{:aufgabe.png?nolink |}}
=== (A2) ===
Eine Vorlage für ein [[ faecher:informatik:oberstufe:php:eingabe:start|HTML Formular mit angebundenem PHP Skript findest du hier]].
* Vollziehe die Beispiele oben nach, bestätige die SQL Injection.
* Erweitere das Formular so, dass man mehrere Parameter der Abfrage dynamisiseren kann. Verwende prepared statements.
* Mache Klassenlisten über ein Dropdown Formularfeld zugänglich (weitere Recherche nötig).