prev up next


Aufgabe 8.5 (25 Punkte)

Erstellen Sie ein Webinterface für Croak auf Basis von PHP. Erzeugen Sie dafür eine PHP-Applikation, die alle bei Aufruf auf dem Server vorhandenen Nachrichten in tabellarischer Form nach Datum sortiert ausgibt und ein Formular mit drei Textfeldern für das Einfügen neuer Nachrichten zur Verfügung stellt. Im ersten und zweiten Textfeld kann ein Benutzername und Passwort angegeben werden, im dritten die Nachricht.

Da beim ersten Aufruf der PHP-Seite noch keine Anmeldedaten für einen Datenbankbenutzer vorhanden sind, können sie sich mit dem Benutzer croak (Passwort: croak) mit der Datenbank verbinden. Er besitzt das select-Recht auf die Datenbank croak.

Implementieren Sie eine geeignete Fehlerbehandlung (mit Rückmeldung an den Nutzer) für zu lange Nachrichten, fehlende Nutzerdaten und verweigerten Datenbankzugriff. Verwenden Sie die in der Vorlesung vorgestellte Tempate Engine HTML_Template_PHPLIB.

Sichern Sie außerdem die Nutzereingabe auf PHP-Seite gegen SQL-Injections, um das Ausführen von illegalen Statements über das Interface zu verhindern (vgl. dazu Abb. 1)


Abb. 1: Litte Bobby Tables (Quelle: xkcd.com)

Technischer Hinweis:

Auf dbs.informatik.uos.de läuft ein Apache Webserver. Für jeden Übungsteilnehmer ist auf dbs ein Verzeichnis angelegt, das vom Webserver erreichbar ist. Wenn Sie Ihre PHP-Dateien im Verzeichnisbaum unter /var/www/dbsuser/[loginname] ablegen, können Sie diese im Web-Browser unter der URL http://dbs.informatik.uos.de/dbsuser/[loginname] abrufen.

Musterlösung vom 22.06.2009:

<?php
require_once 'MDB2.php';
require_once 'HTML/Template/PHPLIB.php';

// Laden des Templates
$template = new HTML_Template_PHPLIB();
$template->setFile("croak", "croak.ihtml");

// Datenbankverbindung aufbauen zum Einfuegen der Daten
if ($_POST['user'] && $_POST['pw'] && $_POST['note']) {
  $dsn = array(
    'phptype'  => 'mysql',
    'username' => $_POST['user'],
    'password' => $_POST['pw'],
    'hostspec' => 'dbs',
    'database' => 'croak',
  );
 
  $con =& MDB2::connect($dsn);
  if (!PEAR::isError($con)) {
    $user = mysql_real_escape_string($_REQUEST['user']);
    $note = mysql_real_escape_string($_REQUEST['note']);
    if (strlen($note) <= 160) {
      $sql = "INSERT INTO nachrichten(nutzer, nachricht) 
              VALUES('".$user."', '".$note."')";

      $result = $con->exec($sql);
      if (PEAR::isError($result))
        $error = $result->getMessage();
      else
        $error = "Daten wurden veroeffentlicht";
    } else
      $error = "Nachricht mehr als 160 Zeichen";
  } else
    $error = $con->getMessage();
} else if ($_POST['user'] || $_POST['pw'] || $_POST['note']) {
  $error = "Die Daten waren nicht vollstaendig";
}
$template->setVar("error", $error);

// Datenbankverbindung aufbauen fuer die Anzeige
$dsn = array(
  'phptype'  => 'mysql',
  'username' => 'croak',
  'password' => 'croak',
  'hostspec' => 'dbs',
  'database' => 'croak',
);
 
$con =& MDB2::connect($dsn);
if (PEAR::isError($con))
  die($con->getMessage());

// wenn ein Suchstring uebergeben wurde, soll gefiltert werden
if ($_REQUEST['search']) {
  // um SQL-Injection zu verhindern, den gesamten Code escapen
  $search = mysql_real_escape_string($_REQUEST['search']);
  $sql = "SELECT * FROM nachrichten WHERE nutzer LIKE '%".$search."%' 
          OR nachricht LIKE '%".$search."%' ORDER BY zeit DESC";
} else {
  $sql = "SELECT * FROM nachrichten ORDER BY zeit DESC";
}

// Ergebnisse besorgen
$result = $con->query($sql);
if (PEAR::isError($result))
  die($result->getMessage());
 
// Laden des Template-Blockes fuer die Nachrichten
$template->setBlock("croak", "row", "rows");
 
// zeilenweise die Nachrichten ins Template einfuegen
while($row = $result->fetchRow()) {
  $template->setVar("user", $row[0]);
  $template->setVar("time", $row[1]);
  $template->setVar("note", chunk_split($row[2], 80, "<br/>"));
  //$template->setVar("note", $row[2]);
 
  // Zeile ins Template einfuegen
  $template->parse("rows", "row", true);
}
// Template ausgeben
$template->pParse("output", "croak");
 
// DB-Verbindung beenden
$result->free();
$con->disconnect();
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
 "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <title>Croak - Webinterface</title>
  </head>
  <body>
    <h1>Croak-Webinterface mit PHP und Templates</h1>
    <br/>
    <h3>Suchen</h3>
    <form method="post" action="./croak.php">
      Suchbegriff: <input type="text" name="search" size="20">
      <input type="submit" value="Suchen"/>
    </form>
    <br/>
    <h3>Nachricht eintragen</h3>
    <div style="color:red;">{error}</div><br/>
    <form method="post" action="./croak.php">
      Benutzername: <input type="text" name="user" size="20" maxlength="8" style="margin-left:10px;"><br/>
      Passwort: <input type="password" name="pw" size="20" style="margin-left:39px;"><br/>
      Nachricht: <input type="text" name="note" size="100" maxlength="160" style="margin-left:36px"><br/>
      <input type="submit" value="kraechzen">
    </form>
    <br/>
    <h3>bisherige Einträge</h3>
    <table border="1" width="100%">
      <tr>
        <th width="100" align="center">Nutzer</th>
        <th width="200" align="center">Zeitpunkt</th>
        <th>Nachricht</th
      </tr>
      <!-- BEGIN row -->
      <tr>
        <td>{user}</td>
        <td>{time}</td>
        <td>{note}</td>
      </tr>
      <!-- END row -->
    </table>
  </body>
</html>


prev up next