Fork me on GitHub

Web Development

Ein Lehrbuch für das Informatik oder Medien-Informatik Studium.

Für die Applikation müssen wir nun auf verschiedene Arten Daten aus der Datenbank lesen.

Einzelne Daten aus der Datenbank lesen

Für die Datei index.php müssen wir die Anzahl der Profile und Projekte anzeigen. Mit der SQL-Funktion COUNT() können wir die Anzahl der gefundenen Datensätze bestimmen*:

Php Code Beispiel aus index.php

$sth = $dbh->query("SELECT COUNT(*) AS anzahl FROM users WHERE profile_visible");
$result = $sth->fetch();
$anz_personen = $result->anzahl;

Hier verwenden wir die Methode fetch() des Statement-Handles um nur einen Datensatz zu lesen.

Man könnte all diese Befehle direkt aneinander-ketten (englisch: “to chain”):

Php Code Beispiel aus index.php

$anz_personen = $dbh->query("SELECT COUNT(*) AS anzahl FROM users WHERE profile_visible")->fetch()->anzahl;

Damit spart man sich zwei der drei Variablen, macht aber die Fehlersuche etwas schwieriger.

Viele Datensätze lesen

Für die Datei personen.php benötigen wir ein Möglichkeit viele Daten aus der Datenbank zu lesen. Das geschieht mit einem einfachen SELECT:

Php Code Abfrage der Datenbank mit SELECT

$sth =$dbh->query(
  "SELECT * FROM person WHERE profile_visible=1 ORDER BY surname LIMIT 500"
);
$personen = $sth->fetchAll();

Die SQL-Anfrage wird hier als String an die query()-Methode des Datenbankhandler übergeben. Der Rückgabewert von query ist ein Statement-Handle $sth (ähnlich dem Datenbank-Handle). Zu diesem Zeitpunkt wurden noch keine Daten von der Datenbank zu PHP übertragen.

Im Beispiel wird LIMIT verwendet: LIMIT anzahl bzw. LIMIT anzahl OFFSET anfangsposition wählt aus der Antwort eine Anzahl von Datensätzen aus, beginnt dabei bei Anfangsposition*.

In der Datenbank sind Personen, deren Profil nicht angezeigt werden soll, mit profile_visible = false gekennzeichnet. Im SQL-Statement wird sicher gestellt, dass nur sichtbare Profil angezeigt werden.

Das eigentliche Lesen der Daten aus der Datenbank geschieht erst nach dem query() mit der Methode fetchAll()*. Der Rückgabewert von fetchAll() ist ein Array mit Objekten. Hier der Output von print_r($personen):

Php Code Output von print_r($personen)

Array
(
  [0] => stdClass Object
      (
          [id] => 422
          [firstname] => Hubert jun.
          [surname] => H.
          [email] => mail422@nowhere.not
          [isfemale] => false
          [profile_visible] => true
      )
  [1] => stdClass Object
      (
          [id] => 313
          [firstname] => Marcel
          [surname] => U
          [email] => mail313@nowhere.not
          [isfemale] => false
          [profile_visible] => true
      )
  ...
)

Später werden die Personen dann angezeigt:

Php Code Anzeige der Personen

foreach($personen as $person) {
  echo "<li>$person->firstname $person->surname</li>\n";
}

Das Array $personen wird hier mit einer foreach-Schleife* abgearbeitet.

Falls man den Index auch anzeigen will, kann man die ausführlichere Version der foreach Schleife verwenden:

Php Code Foreach-Schleife mit index

foreach($personen as $i => $person) {
  echo "<li>Person Nr. $i) $person->firstname $person->surname</li>\n";
}

Achtung: $i ist hier der Index im Array das fetchAll() erzeugt hat, es ist nicht der Primary Key aus der Datenbank! Den würde man mit $person->id erhalten!

Bei der Ausgabe soll für jede Person ein passender Link zu person.php angezeigt werden:

Php Code Link mit ID als Parameter erzeugen

<li>
  <b><?php echo $person->firstname ?> <?php echo $person->surname?></b>
  <a href="person.php?id=<?php echo $person->id ?>">mehr</a>
</li>

Der Output sieht dann zum Beispiel so aus:

Html Code Output des letzten PHP-Programmes

<li>
  <b>Michael A</b>
  <a href="person.php?id=577">mehr</a>
</li>
<li>
  <b>Benjamin A</b>
  <a href="person.php?id=579">mehr</a>
</li>

Auf diese Weise haben wir den Parameter id an den nächsten Teil der Applikation weiter gegeben.

Wir haben in personen.php nur sichtbare Profile angezeigt, und auch nur auf sichtbare Profile verlinkt. Das schützt nicht davor, dass jemand einfach eine URL mit ganz anderer id „von Hand“ eingibt!

http://meinedomain.at/person.php?id=666

Der Zugriffsschutz ist also ein eigenes Thema, das auch in person.php wieder behandelt werden muss.

Einen bestimmten Datensatz lesen

Wenn Sie die Datei person.php mit einem Parameter aufrufen person.php?id=586 soll eine bestimmte Person aus der Datenbank angezeigt werden. Dafür wird der Parameter aus dem $_GET – Array ausgelesen und sicher gestellt, dass es sich wirklich um eine Zahl handelt.

Das Ergebnis der Abfrage kann also sein, dass keine Person gefunden wurde – entweder weil unter diesem Schlüssel gar keine gespeichert ist, oder weil profile_visible=false ist. In diesem Fall gibt fetch kein Objekt sondern der Wert FALSE zurück.

Php Code Beispiel aus index.php

$id = $_GET['id'];  // SICHERHEITSPROBEM - behandeln wir später noch!
$stm = $dbh->query("SELECT * FROM users WHERE profile_visible AND id=$id");
$person = $stm->fetch();
if( $person === FALSE ) {
  die("<p>Konnte keine passenden Daten aus der Datenbank lesen.</p>");
}

Die Darstellung der einzelnen Person ist damit noch nicht fertig programmiert: Die Anzahl der Werke der Person oder eine Liste der Werke fehlen noch.

if( $person->isfemale ) {
    $anrede = "Frau";
    $ersie  = "Sie";
} else {
    $anrede = "Herr";
    $ersie  = "Er";
}

// ====================== Ausgabe ===================
include "header.php";
?>
<p> 
  <?php echo $anrede ?>
  <?php echo $person->firstname ?>
  <?php echo $person->surname ?>
  hat insgesamt x Werke in dieser Datenbank.
  <?php echo $ersie ?> hat die E-Mail Adresse <?php echo $person->email ?>.
</p>

Datensätze suchen

In der Datei psuche.php wird ein Formular zur Suche nach Namen angezeigt:

Html Code Such-Formular in psuche.php

<form action="psuche.php" method="get">
  Suche nach einer Person mit dem Namen <input name="suchwort"> 
  <input type="submit">
</form>

Die eigentliche Suche geschieht über das WHERE-Statement in SQL:

... 
WHERE profile_visible=1 
  AND (surname LIKE '%$suchwort%' OR firstname LIKE '%$suchwort%')

Wir werden uns später noch genauer mit der Sicherheitsproblematik von SQL-Statements befassen, die teilweise aus User-Input entstehen. Noch ignorieren wir die Problematik einfach, und implementieren diese Seite ganz ähnlich wie personen.php.

Zufällige Datensätze auswählen

Auf der Homepage index.php sollen wir 10 zufällig ausgewählte Werke anzeigen. Wie geht das?

Php Code Abfrage von zufälligen Datensätzen in Postgres 9.4

$query =$dbh->query(
  "SELECT * FROM projects WHERE NOT(draft) AND NOT(blocked) ORDER BY RANDOM() LIMIT 10"
);
$personen = $query->fetchAll(PDO::FETCH_OBJ);

Ab Version 9.5 gibt es eine effizientere Methode mit TABLESAMPLE *,

In anderen relationalen Datenbanken gibt es dafür andere Lösungen.

Neue Befehle in diesem Kapitel:

PHP

Postgres