Tag 2 · Block 2 · BK2 · CRUD-Operationen

PDO und Prepared Statements

Das Wichtigste

📖 Lies zuerst im Handout: Handout Tag 2 · Block 2 · Inhalt, Abb. 2.1 und 2.2. Die Aufgaben prüfen, ob du es verstanden hast – nicht, ob du es findest.

Teil 1 · Verstehen

1

DSN zusammensetzen

Ergänze den DSN für unser Docker-Projekt.

mysql:host=____;port=3306;dbname=____;charset=____

📖 Nachlesen: Handout Tag 2 · Block 2 · Inhalt (DSN)

2

Warum nicht localhost?

PHP meldet Connection refused, im DSN steht host=localhost. Warum?

📖 Nachlesen: Handout Tag 2 · Block 2 · MERKE

3

Die drei Pflicht-Optionen

Welche Option ist gemeint?

📖 Nachlesen: Handout Tag 2 · Block 2 · Inhalt und Abb. 2.1

  • Ohne sie merkst du einen SQL-Fehler gar nicht – PDO schluckt ihn still.
  • Zeilen kommen als Array mit den Spaltennamen als Schlüssel.
  • Ohne sie kommt jede Spalte doppelt (einmal mit Name, einmal mit Nummer).
  • Ohne sie baut PHP das Statement nur nach (emuliert).
  • Fehler werfen eine PDOException.
  • Prepared Statements gehen wirklich an die Datenbank.
4

SQL-Injection selbst ausprobieren

Du bist jetzt der Angreifer. Der Code unten holt einen Kurs anhand der id aus der URL. Erreiche die drei Ziele.

📖 Nachlesen: Handout Tag 2 · Block 2 · Prepared Statements und SQL-Injection-Schutz, Abb. 2.2

  1. 1.Hole den Kurs mit der ID 3 (normaler Aufruf).
  2. 2.Unsicher: Finde eine Eingabe, die alle Kurse liefert – obwohl der Code nur einen holen will.
  3. 3.Sicher: Probiere deinen Angriff nochmals mit dem Prepared Statement. Was kommt jetzt zurück?
$id = $_GET['id'];
$stmt = db()->query("SELECT * FROM kurse WHERE id = {$id}");
$kurse = $stmt->fetchAll();
5

Code-Review

Welche Zeilen sind unsicher?

📖 Nachlesen: Handout Tag 2 · Block 2 · ACHTUNG («String-Konkatenation in SQL ist das Alarm-Signal»)

Mehrere Antworten richtig.

6

fetch() oder fetchAll()?

Was brauchst du bzw. was kommt zurück?

📖 Nachlesen: Handout Tag 2 · Block 2 · Inhalt (letzter Absatz)

Antwort
getAllKurse() – Liste aller Kurse
getKursById(3) – genau ein Kurs
Was liefert fetch(), wenn keine Zeile passt?

Teil 2 · In deinem Projekt

Lab 2.2 – PDO-Verbindung und erste Abfragen

Erst wenn Teil 1 erledigt ist. Dann hast du alles, was du dafür brauchst.

Arbeite allein in deinem eigenen Projekt. Der Walkthrough im Handout ist deine Notfall-Hilfe – versuch es zuerst ohne.

  1. Erstelle src/db.php mit der Funktion db() (Singleton).
  2. Erstelle src/KursRepository.php mit getAllKurse(): array (nutzt query()).
  3. Erweitere sie um getKursById(int $id): ?array (nutzt prepare()).
  4. Verdrahte beide in public/index.php und gib das Ergebnis als JSON mit korrektem Header aus.
  5. Teste mit curl http://localhost:8080/ – erwartet: ein JSON-Array.

Akzeptanzkriterien – hake ab, was bei dir läuft

Zum Schluss: committen und pushen

git add .
git commit -m "feat: PDO-Verbindung und KursRepository (Lab 2.2)"
git push