quakenet:#php Tutorial

Author: Progman, zuletzt bearbeitet von progman @ 2003/12/05 17:56:35

Bitte beachten Sie, dass die Tutorialkapitel zusammenhängen. Wenn sie direkt auf ein Kapitel verlinkt wurden müssen Sie gegebenenfalls die vorherigen Kapitel auch lesen. Achten Sie beim lesen darauf, dass Sie kein Kapitel überspringen.

PEAR::DB

  1. Vorbereitung
  2. Aufbau des Scripts

1. Vorbereitung

Als erstes PEAR Beispiel nehmen wir die PEAR::DB Klasse. Wir werden diese Klasse mit MySQL und Smarty benutzen, stellt also sicher, dass diese Sachen 'betriebsbereit' sind.

2. Aufbau des Scripts

Bevor wir mit der PEAR::DB Klasse arbeiten können müssen wir diese erstmal in das Script laden. Dies kann man mit include machen, aber im PEAR Manual steht require_once. Dies benutzen wir nun auch.

<?php
    error_reporting
(E_ALL);
    require_once
'DB.php'; // PEAR::DB laden
    
require_once 'Smarty.class.php'; // Smarty laden
?>

Wir brauchen keine extra Pfade bei der DB.php angeben, weil sicht diese Datei im /usr/lib/php/ Verzeichnis befindet. Bei der Datei für die Smarty-Klasse muss man ggf. den Pfad ändern.

Zuerst erzeugen wir ein Smarty Objekt und zeigen 2 statische Teplates header.tpl und menu.tpl

<?php
    $smarty
= new Smarty;

    
$smarty->display('header.tpl');
    
$smarty->display('menu.tpl');
?>

Die header.tpl hat folgenden Inhalt:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Testen macht spaß</title>
        <link rel="stylesheet" href="style.css" media="screen" />
    </head>
    <body>
        

Und die menu.tpl:

<ul id="menu">
    <li>
        <a href="#">Startseite</a>
    </li>
    <li>
        <a href="#">IRC</a>
    </li>
    <li>
        <a href="#">HTML</a>
    </li>
    <li>
        <a href="#">PHP</a>
    </li>
    <li>
        <a href="#">Über diese Seite</a>
    </li>
</ul>
        

Die beiden Dateien kann man natürlich entsprechend verändern, wie man es möchte.

Um sich bei einer Datenbank einzuloggen, haben sich die Leute von PEAR was einfallen lassen. Die DB-Klasse von PEAR ist unabhängig vom Typ der Datenbank. Um seine Datenbank auszuwählen, in der man arbeiten möchte, muss man ein DSN - Data Source Name benutzen. So ein DSN ist für MySQL wie folg aufgebaut:

mysql://user:pass@host/database
        

Wie man erkennt, sieht dies so ähnlich wie eine gewöhnliche URL aus. Man muss hier nur seine Daten entsprechend einsetzen.

<?php
    $dsn
= "mysql://pageuser:foobar@localhost/mypage";
?>

Mit der Methode connect lassen wir uns ein DB-Handler zurückliefern. Wir brauchen auch kein Objekt von der Klasse DB, wir rufen die Methode einfach mit dem :: Operator auf. Als Parameter müssen wir dieses DSN übergeben.

<?php
    $db
= DB::connect($dsn);
?>

DB::connect erstellt, abhängig vom DSN, ein Objekt vom Typ DB_xxx, wobei das xxx für den Typ der Datenbank steht. Natürlich müssen wir noch prüfen, ob der Verbindungsaufbau erfolgreich war.

<?php
    
if(DB::isError($db)) {
        die(
$db->getMessage());
    }
?>

Mit der Methode isError wird geguckt, ob das Objekt $db ein Error-Objekt der Klasse DB_Error ist. Diese wird, wenn der Verbindungsaufbau nicht geklappt hat, von der Methode connect zurückgegeben. Wie man sieht läuft hier alles Objektorientiert ab. Fallst ein Fehler aufgetreten ist, rufen wir die Methode getMessage auf. Diese liefert uns eine entsprechende Fehlermeldung zurück. Diese Methode liefert uns nur wenig Informationen über den Fehler. Wenn man genauere Informationen haben möchte, muss man die Methode getDebugInfo benutzen. Doch diese Methode sollte man nicht für Debuginfos an den Besucher der Seite schicken. Es macht mehr Sinn, wenn der Besucher der Seite die 'einfache' Fehlermeldung von getMessage() sieht und die genauere Fehlermeldung von getDebugInfo per email an den Admin schickt. Somit weiß der Admin sofort, dass ein Fehler in der Seite ist und der Besucher der Seite sieht keine Wichtigen Logindaten wie Username und Password. Deswegen sollte man auch immer getMessage() und wirklich nur zur Fehlersuche getDebugInfo() verwenden.

Nachdem man erfolgreich eingeloggt ist, kann man mit der Datenbank arbeiten. Zuerst speichern wir unseren Query in eine extra Variable, wie üblich.

<?php
    $sql
= "SELECT
                ID,
                Titel,
                Inhalt,
                Datum,
                Autor
            FROM
                News
            ORDER BY
                Datum DESC;"
;
?>

Diesen Query schicken wir mit der Methode query ab. Nun benutzen wir aber unser erstelltest DB_MySQL-Objekt $db, deswegen haben wir es ja erstellt. Den Rückgabewert speichern wir in eine extra Variable.

<?php
    $result
= $db->query($sql);
?>

Dieser Rückgabewert ist entweder ein Objekt der Klasse DB_Result oder ein Error-Objekt wie oben. Wir können also die selbe Abfrage benutzen.

<?php
    
if(DB::isError($result)) {
        die(
$result->getMessage());
    }
?>

Für Smarty will ich die ganzen News mit den Kommentaren in ein Array speichern. Dafür leg ich ein leeres Array an.

<?php
    $news
= array();
?>

Um nun ein Datensatz auszulesen benutzen wir die Methode fetchrow. Mit dem Optionalen Parameter können wir einstellen, wie wir die Datensätze auslesen wollen. Standardmäßig wird ein numerisches Array mit Zahlen als Indize zurückgeliefert. Da ich das aber nicht gebrauchen kann, werde ich die Konstante DB_FETCHMODE_ASSOC als Parameter benutzen. Dadurch liefert mir diese Funktion, wie üblich, den Datensatz als assoziatives Array zurück. Andere Konstanten sind DB_FETCHMODE_ORDERED, der Standardmäßig genommen wird wenn kein Parameter angegeben wurd, und noch DB_FETCHMODE_OBJECT um ein Objekt mit entsprechenden Eigenschaften zurückzuliefern. Dies kann man alles im PEAR Manual unter DB Introduction - Fetch nachlesen.

<?php
    
while($row = $result->fetchrow(DB_FETCHMODE_ASSOC)) {
?>

Die Kommentare lesen wir mit einem inneren Query nach dem gleichen Prozedere aus.

<?php
    $sql
= "SELECT
                Link,
                Beschreibung
            FROM
                News_Links
            WHERE
                NewsID='"
.$row['ID']."';";
    
$reslink = $db->query($sql);
    if(
DB::isError($reslink)) {
        die(
$reslink->getMessage());
    }

    
$links = array();
    while(
$link = $reslink->fetchrow(DB_FETCHMODE_ASSOC)) {
        
$links[] = $link;
    }
?>

Und nun speichern wir alles in das Array $news.

<?php
    $tmparray
= $row;
    unset(
$tmparray['ID']);
    
$tmparray['Links'] = $links;
    
$news[] = $tmparray;
?>

Zuerst speichern wir die News in ein tmp-Array, dann löschen die ID, speichern die Links und das tmp-Array dann in das news-Array. Nun sind wir fertig und verlassen die while-schleife.

<?php
    
}
?>

(Der Beispielcode hats gebracht)

Die Variable $news speichern wir nun in Smarty, damit wir in den Templates darauf zugreifen können.

<?php
    $smarty
->assign('newsbeitraege', $news);
?>

Nun lassen wir die News mit einem entsprechenden Template anzeigen.

<?php
    $smarty
->display('news.tpl');
?>
<div id="content">
    <h2>Startseite</h2>
    <ul id="news">
    {foreach from=$newsbeitraege item=newsbeitrag}
        <li>
            <h3>
                {$newsbeitrag.Titel}
            </h3>
            <p class="newsheader">
            {$newsbeitrag.Autor} @ {$newsbeitrag.Datum}
            </p>
            <p class="newsinhalt">
                {$newsbeitrag.Inhalt}
            </p>
            <ul>
            {foreach from=$newsbeitrag.Links item=link}
                <li>
                    <a href="{$link.Link}">{$link.Beschreibung}</a>
                </li>
            {/foreach}
            </ul>
        </li>
    {/foreach}
    </ul>
</div>
        

Nun machen wir den Speicher für den MySQL-Query frei und beenden die Verbindung mit der Datenbank.

<?php
    $result
->free();

    
$db->disconnect();
>

Und als letztes zeigen wir noch einen footer an, der die HTML-Datei sauber beendet.

<?php
    $smarty
->display('footer.tpl');
?>
    </body>
</html>
        

Die CSS-Datei style.css könnte so aussehen.

body {
    background-color: #EEE;
}
#menu {
    float: right;
    border: 1px solid black;
    background-color: #FFF;
    list-style-type: none;
    margin-left: 0px;
    margin-top: 0px;
    margin-right: 10px;
    width: 20%;
}
#content {

}
#content h2 {
    text-align: center;
    background-color: #FFF;
    border: 1px solid black;
    margin-top: 0px;
    width: 77%;
}
#news {
    list-style-type: none;
    margin-left: 0px;
}
#news .newsheader {
    margin: 0px;
    font-style: italic;
}
#news h3 {
    color: blue;
}
        

Nun kann man ein paar Datensätze mit PHPMyAdmin hinzufügen und das Script testen. Die Scripte liegen alle online im Script-Archiv unter /tutorial/testpage/

Fragen zum aktuellen Thema

  1. Wie Prüfe ich nach, ob eine Aktion mit MySQL Fehlerhaft war?
Wie Prüfe ich nach, ob eine Aktion mit MySQL Fehlerhaft war?

Die Datenbankklasse DB hat eine Methode isError. Mit dieser Methode kann man prüfen ob ein Objekt eine Instanz der Klasse DB_Error ist oder nicht. Mit diesem Objekt kann man dann die Methoden getMessage und getDebugInfo aufrufen, um mehr Informationen über den Fehler zu erfahren.

Nach oben