Q2 Datenbanken

PHP und PDO: die erste Ausgabe

Lösung geprüft

Die Aufgabe der heutigen Stunde ist die erste PHP-Seite mit Datenbankzugriff! Bis jetzt haben wir SQL immer direkt in phpMyAdmin eingetippt. Jetzt holt ein Programm die Daten und gibt sie als Webseite aus – und genau dafür gibt es PDO.

Die Aufgabenstellung lautet

Aufgabe 1: PHP und PDO. Eine einfache Ausgabe mit PDO in PHP. PHP-Datei hier einfügen.

Die Testdatenbank „schule"

Alle PHP-Aufgaben laufen auf derselben Datenbank:

Schüler(id, nachname, vorname, geburtsdatum, strassenr, plz, ort)
Kurs(id, f_id, art, stufe, wochenstunden)
Fach(id, fach)
belegt(s_id, k_id, punkte)
leitet(s_id, ng_id, stunden)
Nachhilfegruppe(id, f_id)
erDiagram
    Fach ||--o{ Kurs : "f_id"
    Fach ||--o{ Nachhilfegruppe : "f_id"
    "Schüler" ||--o{ belegt : "s_id"
    Kurs ||--o{ belegt : "k_id"
    "Schüler" ||--o{ leitet : "s_id"
    Nachhilfegruppe ||--o{ leitet : "ng_id"
    "Schüler" {
        int id PK
        string nachname
        string vorname
        date geburtsdatum
        string strassenr
        int plz
        string ort
    }
    Fach {
        int id PK
        string fach
    }
    Kurs {
        int id PK
        int f_id FK
        string art
        string stufe
        int wochenstunden
    }
    belegt {
        int s_id FK
        int k_id FK
        int punkte
    }
    Nachhilfegruppe {
        int id PK
        int f_id FK
    }
    leitet {
        int s_id FK
        int ng_id FK
        int stunden
    }
Die Testdatenbank schule im Überblick

Warum PDO und nicht etwas anderes

In PHP gibt es drei Wege, auf eine MySQL-Datenbank zuzugreifen:

WegStand
mysql_*veraltet, in PHP 7 komplett entfernt – gar nicht erst anfangen
MySQLifunktioniert, aber nur für MySQL
PDOdas aktuellste Interface, funktioniert auch mit anderen Datenbanksystemen

Wenn du im Netz ein Tutorial findest, in dem mysql_query(...) steht: zuklappen und ein anderes suchen. Das ist mindestens zehn Jahre alt und läuft auf keinem aktuellen Server mehr.

sequenceDiagram
    participant B as Browser
    participant P as ausgabe.php
    participant D as PDO
    participant M as MySQL

    B->>P: Aufruf von ausgabe.php
    P->>D: new PDO(...schule)
    D->>M: verbinden,<br>SET NAMES utf8
    M-->>D: Verbindung steht
    P->>D: query("SELECT *<br>FROM schüler")
    D->>M: SQL absetzen
    M-->>D: Ergebniszeilen
    D-->>P: Ergebnis zum<br>Durchlaufen
    P->>P: foreach:<br>$row['vorname'],<br>$row['nachname']
    P-->>B: fertiges HTML
Der Weg vom Browser zur Datenbank und zurück

Lösungsprozess der Aufgabe

ausgabe.php
/* meininfokurs.cmrg.site */
<?php
/**
 *
 * Eine einfache Ausgabe mit PDO
 *
 * @version 1.0 vom 16.05.2019
 * @meininfokurs.cmrg.site
 */

// Verbindung zur Datenbank aufbauen
$pdo = new PDO('mysql:host=localhost;dbname=schule', 'root', '',
       array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));

$sql = "SELECT * FROM schüler";

// Variante 1: direkt ueber query() und foreach
foreach ($pdo->query($sql) as $row) {
    echo $row['vorname']." ".$row['nachname']."<br />";
}

// Variante 2: ueber prepare() und execute()
$sth = $pdo->prepare("SELECT * FROM schüler");
$sth->execute();

echo '<br/>';
/* Alle Datensätze ausgeben */
print("Alle Datensätze ausgeben:");
echo '<br/>';
$result = $sth->fetchAll();
print_r($result);
?>

Die Verbindungszeile

$pdo = new PDO('mysql:host=localhost;dbname=schule', 'root', '',
       array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
TeilBedeutung
mysql:host=localhostDatenbanktyp und Server – bei XAMPP läuft beides auf dem eigenen Rechner
dbname=schulewelche Datenbank
'root'Benutzername
''Passwort – bei XAMPP standardmäßig leer
SET NAMES utf8Zeichensatz, damit Umlaute nicht als Fragezeichen erscheinen

Das utf8 ist kein Luxus. Ohne das steht in der Ausgabe „Müller" statt „Müller" und der Tabellenname schüler funktioniert auch nicht. Das ist der Fehler, den bei dieser Aufgabe fast jeder einmal hat.

Benutzer root ohne Passwort ist nur in Ordnung, weil das alles lokal in XAMPP auf dem eigenen Rechner läuft. Auf einem echten Server legt man einen eigenen Benutzer an, der nur auf diese eine Datenbank darf – und gibt ihm ein Passwort.

query() und foreach

foreach ($pdo->query($sql) as $row) {
    echo $row['vorname']." ".$row['nachname']."<br />";
}

query() schickt das SQL an die Datenbank und gibt etwas zurück, das man mit foreach durchlaufen kann – genau wie eine ArrayList in Java. Jeder Durchlauf liefert eine Zeile in $row.

$row['vorname'] greift über den Spaltennamen zu. So ein Array nennt man assoziativ: der Index ist kein Zähler, sondern ein Text. In Aufgabe 5 kommt die Variante ohne das noch dran.

Der Punkt . ist in PHP das, was in Java das Plus ist: er hängt Texte aneinander. Wer aus Java kommt, schreibt hier reflexhaft ein + – das ergibt in PHP aber eine Addition und damit meistens eine 0.

prepare() und execute()

$sth = $pdo->prepare("SELECT * FROM schüler");
$sth->execute();
$result = $sth->fetchAll();

Der zweite Weg macht dasselbe in zwei Schritten: erst die Anfrage vorbereiten, dann ausführen. Das sieht umständlicher aus und ist es hier auch – sobald aber Benutzereingaben in die Abfrage kommen, ist dieser Weg der einzig richtige. Warum, kommt beim Thema SQL-Injection.

fetchAll() holt alle Zeilen auf einmal in ein Array, und print_r() gibt dieses Array mit allen Schlüsseln aus. Das ist kein hübscher Output für eine Webseite, aber unschlagbar zum Nachschauen, wie die Daten überhaupt aussehen.

Die Ausgabe

Browser
Müller Peter
Gamler Kevin
Ritter Jörg
Ritter Miriam
Rose Stefanie
Sproß Marie
Klasen Daniel
Margel Lukas

Alle Datensätze ausgeben:
Array ( [0] => Array ( [id] => 1 [0] => 1 [nachname] => Peter [1] => Peter ... ) ... )

Beim print_r fällt etwas auf: jeder Wert steht zweimal drin – einmal unter dem Spaltennamen und einmal unter einer Nummer. PDO liefert standardmäßig beides. Genau darauf baut Aufgabe 5 auf, die nur mit den Nummern arbeitet.

Übrigens: <br /> im echo ist HTML, kein PHP. Ein \n würde im Quelltext einen Zeilenumbruch machen, im Browser aber nichts – dort muss ein <br> stehen.

Aufgabe suchen

Tippe los. Strg+K öffnet die Suche von überall.

Zuletzt angesehen

Werbung