Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Geleitwort
Vorwort
1 PEAR – Einführung
2 Authentication
3 Caching
4 Date and Time
5 File Formats
6 HTTP
7 Internationalization
8 Mail
9 Networking
10 PHP
11 Text
12 Web Services
13 Benchmarking
14 Configuration
15 Database
16 File System
17 HTML
18 Images
19 Logging
20 Math
21 Numbers
22 Tools and Utilities
23 XML
24 Selbst Pakete erstellen
25 PECL
Index
Ihre Meinung?

Spacer
 <<   zurück
PHP PEAR von Carsten Möhrke
Anwendung und Entwicklung – Erweiterungen für PHP schreiben
Buch: PHP PEAR

PHP PEAR
798 S., 39,90 Euro
Rheinwerk Computing
ISBN 3-89842-580-0
gp 15 Database
  gp 15.1 DB
    gp 15.1.1 prepare(  ) und execute(  )
    gp 15.1.2 Informationen über Tabellen und Datenbank
    gp 15.1.3 Quoting/Escaping
    gp 15.1.4 Transaktionsorientierung
  gp 15.2 DB_NestedSet
  gp 15.3 DB_QueryTool
  gp 15.4 DB_Table
    gp 15.4.1 Einfügen von Werten
    gp 15.4.2 Nutzung von Formularen
    gp 15.4.3 Auslesen von Werten
    gp 15.4.4 Manipulation von Daten


Rheinwerk Computing

15.3 DB_QueryTool  toptop


Besprochene Version: 1.0.0 Lizenz: PHP-Lizenz 3
Klassendatei(en): DB/QueryTool.php

Das Paket DB_QueryTool ist eine Ergänzung zum Paket PEAR::DB und abstrahiert den Zugriff auf eine Datenbank-Tabelle noch weiter, als DB das tut. Wenn Sie DB_QueryTool nutzen, müssen Sie sich nicht mehr mit der Syntax von SQL-Befehlen quälen, sondern können einfach auf Methoden zurückgreifen, die die SQL-Befehle automatisch generieren. Zwei Dinge sind hierbei zu beachten.

Zum Ersten sollten Sie schon eine gute Vorstellung davon haben, wie der Zugriff auf eine Tabelle mithilfe von SQL funktioniert. Zwar benötigen Sie keine Kenntnisse in der SQL-Syntax, aber die Logik, die SQL nutzt, findet sich in den Methoden wieder.

Zum Zweiten können die Methoden natürlich nicht ganz so flexibel auf eine Tabelle zugreifen wie ein SQL-Befehl, der manuell erstellt wurde. Allerdings sind die Methoden schon sehr flexibel, so dass der größte Teil der benötigten Befehle sicher mit dem Paket abgebildet werden kann.

Wenn Sie auf der PEAR-Webseite eine Dokumentation zu dem Paket suchen, sollten Sie die Dokumentation des Paketes MDB_QueryTool nutzen. MDB_QueryTool ist voll kompatibel zu DB_QueryTool, so dass keine eigene Dokumentation erstellt wurde.

Für die folgenden Beispiele wird eine Tabelle genutzt, die mit diesem Befehl angelegt wurde:

create table mitarbeiter ( 
   id integer, 
   vorname varchar(30), 
   nachname varchar(30), 
   position enum ('AL','MA'), 
   einkommen float, 
   primary key (id) 
)

Des Weiteren wurde mithilfe des Pakets DB eine Sequenz definiert, die zum Generieren der ID genutzt wird und den Namen mitarbeiter_seq hat.

Zur Nutzung des Pakets leiten Sie eine neue Klasse ab, die die Klasse DB_QueryTool als Elternklasse nutzt. In der abgeleiteten Klasse müssen Sie die Eigenschaften $table und $sequenceName überschreiben. In der ersten legen Sie den Namen der Tabelle ab, die genutzt werden soll, und in der zweiten den Namen der Sequenz, die für die Tabelle genutzt wird.

Bitte wundern Sie sich nicht, dass die Eigenschaften in dem Beispiel als public deklariert sind. Das ist nicht unbedingt sinnvoll, da nicht von außen auf die Eigenschaften zugegriffen werden soll. In der Superklasse ist die Eigenschaft allerdings als public deklariert. Somit muss sie hier auch entsprechend eingerichtet werden.

Die Eigenschaft $primaryCol bekommt den Namen der Spalte zugewiesen, die der Primärschlüssel ist. Heißt die Spalte id, wäre es nicht notwendig, die Eigenschaft mit dem Namen zu belegen, da es sich bei id um den Default-Wert handelt. Hierbei muss es sich nicht zwingend um einen Primärschlüssel im eigentlichen Sinne handeln. Vielmehr ist es die Spalte, in die bei einem INSERT automatisch die ID eingefügt wird und die per Default für Vergleiche beim Löschen oder Ähnlichem herangezogen wird.

Mithilfe der Eigenschaft $tableSpec können Sie noch einen Namen definieren, unter dem Sie die Tabelle ansprechen können.

require_once ('DB/QueryTool.php'); 
 
// Konstante definieren, um einheitlichen 
// Namen zu gewaehrleisten 
define ('TABELLE','mitarbeiter'); 
 
// Neue Klasse deklarieren 
class mitarbeiter extends DB_QueryTool 
{ 
   // Eigenschaften korrekt belegen 
   public $table = TABELLE; 
   public $sequenceName = TABELLE; 
 
   public $primaryCol = 'id'; 
 
   // Tabelle mitarbeiter kann unter dem Namen ma 
   // angesprochen werden. 
   public $tableSpec = array( 
                          array('name' => TABELLE, 
                                'shortName' => 'ma') 
                       ); 
} 
 
// DSN zum Zugriff auf die Datenbank 
$dsn = 'mysql://user:passwort@localhost/netviser'; 
 
// Neues Objekt ableiten 
$tabelle = new mitarbeiter($dsn); 
// Objekt in den Ursprungszustand versetzen 
$tabelle->reset(); 
// Alle Daten auslesen (SELECT * FROM mitarbeiter) 
$res = $tabelle->getAll();

Listing 15.8 Auslesen einer kompletten Tabelle mit DB_QueryTool

Der Konstruktor der Klasse bekommt den DSN, der zum Zugriff auf die Datenbank verwendet werden soll, als Parameter übergeben. Bevor Sie anfangen, einen neuen Befehl vorzubereiten, sollten Sie immer zuerst die Methode reset() aufrufen. Diese sorgt dafür, dass alle Einstellungen gelöscht werden, die eventuell noch oder schon im Objekt vorhanden sind.

Die Methode getAll() ist eine der einfachsten Methoden. Sie entspricht einem SELECT * FROM mitarbeiter und liefert die komplette Tabelle als indiziertes Array zurück.

Für jede Tabellenzeile ist ein eigenes assoziatives Array enthalten, in dem die Daten enthalten sind. Die Namen der Spalten fungieren dabei als Schlüssel. Ein solcher Eintrag könnte so aussehen:

  [0]=> 
  array(5) { 
    ["id"]=> 
    string(1) "1" 
    ["vorname"]=> 
    string(5) "Monty" 
    ["nachanme"]=> 
    string(5) "Burns" 
    ["position"]=> 
    string(2) "AL" 
    ["einkommen"]=> 
    string(4) "8000" 
  } 
// weitere Werte

Auch wenn die Nutzung des Pakets einfach und unproblematisch ist, sollten Sie Ihren Code ausführlich testen. Leider funktioniert die Fehlerbehandlung zurzeit noch nicht, so dass unter Umständen eine Fehlermeldung auf dem Bildschirm ausgegeben wird.

Der Methode getAll() können Sie auch noch zwei Zahlen als Parameter übergeben. Der erste definiert, ab welchem Wert die Daten aus der Tabelle ausgegeben werden. Übergeben Sie also eine 1 an erster Stelle, wird der »nullte« Eintrag in der Datenbank übersprungen. Mit der zweiten Zahl können Sie definieren, wie viele Einträge maximal zurückgegeben werden, um ein Blättern zu vereinfachen.

Die meisten Methoden dieser Klasse sind ähnlich einfach zu nutzen wie getAll(). Eine andere Möglichkeit, um Daten auszulesen, ist get(). Als ersten Parameter bekommt sie einen Wert übergeben, der dem primären Schlüssel einer Zeile entspricht. Diese Zeile wird ausgelesen und als Array zurückgeliefert. Sollte eine entsprechende Zeile nicht gefunden werden, gibt die Methode false zurück. Als zweiten Wert können Sie noch den Namen einer Spalte übergeben. In dem Fall wird nur der Wert zurückgegeben, der durch Zeile und Spalte definiert ist. Dieser wird nicht als Array, sondern direkt zurückgegeben.

Die letzte Methode zum Auslesen von Werten ist getCol(), die Ihnen eine komplette Spalte mit Werten in Form eines Arrays zurückgibt. Der Name der Spalte wird als Parameter übergeben. Die Methode ist nicht in der Lage, mehrere Spalten auf einmal auszulesen.

Das Verhalten dieser Methoden können Sie noch mit den Methoden setSelect() und setLimit() beeinflussen. Die beiden Methoden müssen jeweils vor den get-Methoden aufgerufen werden. setSelect() bekommt den Namen einer oder mehrerer Spalten übergeben, die durch ein Komma zu trennen sind. get() und getAll() liefern dann nur die Werte dieser Spalten zurück. Eine Kombination mit getCol() macht natürlich keinen Sinn.

setLimit() dient dazu, die Anzahl der zurückgegebenen Ergebnisse zu limitieren, wie das auch bei getAll() möglich ist. Auch hier werden zwei Zahlen übergeben, wobei die erste definiert, welches der erste Wert ist, der zurückgegeben werden soll, und die zweite die Anzahl der Werte bestimmt.

Bevor ich zu komplexeren Abfragen komme, noch ein kleiner Tipp: Das Paket kennt die Methode getQueryString(), mit der Sie den SQL-Befehl auslesen können, den das Objekt nutzt bzw. genutzt hat. Mit den Zeilen

// Ableiten des Objekts wie in 
$res = $tabelle->getAll(); 
echo $tabelle->getQueryString();

erhalten Sie den folgenden SQL-Befehl als Ausgabe:

SELECT mitarbeiter.id AS "id", 
      mitarbeiter.vorname AS "vorname", 
      mitarbeiter.nachname AS "nachname", 
      mitarbeiter.position AS "position", 
      mitarbeiter.einkommen AS "einkommen" 
      FROM mitarbeiter

Diese Methode ist immer sehr hilfreich, wenn Sie einen Fehler suchen müssen oder das Paket nutzen wollen, um SQL-Code generieren zu lassen, den Sie dann in eigene Projekte einbinden. Leider liefert die Methode nur SELECT-Befehle zurück. Möchten Sie bei anderen Befehlen »hinter die Kulissen« schauen, können Sie die Eigenschaft _lastQuery ausgeben lassen. Hier wird immer die zuletzt ausgeführte Abfrage abgelegt. Allerdings sollte die Eigenschaft als private betrachtet und nicht direkt ausgegeben werden. Die korrekte Variante zum Analysieren der Abfragen ist es, die Methode debug() zu überschreiben. Diese ist leer definiert und wird jedes Mal aufgerufen, bevor ein SQL-Befehl an die Datenbank geschickt wird. In der Deklaration der Klasse müssten Sie also eine Methode wie diese vorsehen:

function debug ($sql) 
{ 
   echo $sql; 
}

Für sehr umfangreiche Applikationen ist die Klasse auch in der Lage, mit einem Logfile zu arbeiten.

Um die zurückgegebenen Daten zu sortieren, nutzen Sie die Methode setOrder(). Diese bekommt als ersten Parameter den Namen der Spalte übergeben, nach der sortiert werden soll. Nutzen Sie als zweiten Parameter ein true, wird absteigend sortiert.

Sie können der Methode durchaus auch mehrere Spaltennamen übergeben, nach denen sortiert werden soll. Diese werden als ein String, getrennt durch Kommas, übergeben. Möchten Sie absteigend sortieren, so bezieht sich das DESC allerdings immer nur auf die letzte Spalte.

// Ableitung des Objekts etc. 
$tabelle->setSelect('vorname,nachname'); 
$tabelle->setOrder('vorname,nachname',true); 
$res = $tabelle->getAll();

Die drei vorhergehenden Zeilen generieren also diesen SQL-Befehl:

SELECT mitarbeiter.vorname,mitarbeiter.nachname 
       FROM mitarbeiter 
       ORDER BY mitarbeiter.vorname, 
                mitarbeiter.nachname DESC

Möchten Sie eine WHERE-Klausel einfügen, können Sie die Methode setWhere() nutzen, der Sie die Bedingung als String übergeben, also zum Beispiel $tabelle->setWhere ('einkommen > 3000');. Benötigen Sie mehrere Bedingungen, die mit AND oder OR verknüpft sind, können Sie diese als fertigen String an die Methode übergeben. Rufen Sie die Methode mehrfach auf, so wird jeweils der vorhergehende Aufruf überschrieben. Alternativ können Sie auch weitere Bedingungen mithilfe von addWhere() hinzufügen. addWhere() bekommt als ersten Parameter die Bedingung übergeben, die hinzugefügt werden soll. Diese wird mit einem AND angehängt, wenn Sie als zweiten Parameter nicht ein 'OR' übergeben.

Eine besondere Form des addWhere() ist das addWhereSearch(). Hierbei wird eine Stichwortsuche implementiert. Suchen Sie beispielsweise den Nachnamen Maier oder Mayer, so könnten Sie in der Spalte nachname nach den Strings ma und er suchen.

$tabelle->addWhereSearch('nachname','ma er');

Die WHERE-Klausel lautet in dem Fall dann WHERE LOWER(nachname) LIKE '%ma%er%'. Auch wenn der Name der Methode mit add beginnt, müssen Sie vorher nicht eine WHERE-Bedingung mit setWhere() festgelegt haben.

Natürlich ist es auch möglich, mit HAVING oder GROUP BY zu arbeiten. setHaving() und addHaving() sind parameterkompatibel zu setWhere() und addWhere(). Um eine Gruppierung festzulegen, übergeben Sie der Methode setGroup() den Namen der Spalte, die für das GROUP BY genutzt werden soll.

Um ein JOIN zu nutzen, stehen die Methoden setLeftJoin() und setRightJoin() zur Verfügung. Beide Methoden bekommen als ersten Parameter den Namen der Tabelle übergeben, mit der die Tabelle verquickt werden soll. Als zweiter Parameter folgt dann die WHERE-Bedingung, die eingebunden werden soll. Weitere JOINs können Sie mit addLeftJoin() und addRightJoin() hinzufügen, die dieselben Parameter unterstützen wie die beiden set-Methoden.

Möchten Sie Daten in der Tabelle ablegen, nutzen Sie die Methode save(). Sie bekommt ein Array übergeben, bei dem die Namen der Spalten als Schlüssel genutzt werden, die dann auf die einzufügenden Werte verweisen. Sie können für die Spalte, die als Primärschlüssel genutzt wird, einen Wert übergeben. Machen Sie das nicht, wird automatisch der nächste Wert aus der Sequenz genutzt, die bei der Deklaration der Klasse angegeben wurde.

$data = array ('vorname' => 'Elmer', 
               'nachname' => 'Fudd'); 
$tabelle->save($data);

Genauso einfach wie das Einfügen von Daten ist es, Daten zu verändern. Die Methode update() bekommt ein Array mit Werten übergeben, das identisch zu dem bei save() genutzten Array aufzubauen ist. Bitte vergessen Sie nicht, vor der Nutzung dieser Methode setWhere() aufzurufen, wenn Sie nicht die gesamte Tabelle verändern wollen.

Um Daten aus der Tabelle zu entfernen, stehen remove(), removeMultiple(), removePrimary() und removeAll() zur Verfügung. removeAll() löscht alle Daten aus der Tabelle und sollte somit mit Vorsicht eingesetzt werden. Aber auch die Methode remove() ist nicht ungefährlich. Die bekommt als ersten Parameter einen Wert übergeben und als zweiten den Namen einer Spalte, in der der Wert enthalten ist. Geben Sie den Namen der Spalte nicht an, wird der übergebene Wert mit dem Primärschlüssel verglichen. Wenn Sie die Methode so aufrufen:

$tabelle->remove('Monty','vorname');

würde sich dieser SQL-Befehl ergeben:

DELETE FROM mitarbeiter WHERE vorname = 'Monty'

Um eine komplexere Abfrage zu generieren, können Sie an erster Stelle auch ein Array übergeben. In dem Fall werden die Schlüssel und Werte mit einem Gleichheitszeichen zu einer Bedingung verbunden und die Bedingungen mit einem AND verknüpft. Der Aufruf

$wheres = array ('vorname' => 'Monty', 
                 'nachname' => 'Burns'); 
$tabelle->remove($wheres);

ergibt diesen SQL-Befehl:

DELETE FROM mitarbeiter 
            WHERE vorname = 'Monty' 
            AND nachname = 'Burns';

Wenn Sie die Methode remove() nutzen, so achten Sie bitte peinlich genau auf die übergebenen Parameter, da die Methode weder die Plausibilität noch die Validität der Werte prüft.

removeMultiple() ist der Methode remove() sehr ähnlich. Allerdings ist sie darauf ausgelegt, mehrere Zeilen auf einmal zu entfernen, und bekommt daher ein Array von Werten an erster Stelle übergeben. Auch hier können Sie an zweiter Stelle einen Spaltennamen übergeben. Machen Sie das nicht, werden die Werte mit dem Primärschlüssel verglichen.

Die Methode removePrimary() fällt ein wenig aus der Reihe. Sie dient dazu, Werte in anderen Tabellen zu entfernen, und könnte auch statisch aufgerufen werden. Als ersten Parameter bekommt sie einen Wert und als zweiten den Namen einer Spalte übergeben. Danach folgt eine beliebige Anzahl von DB_QueryTool-Objekten. Für jedes der Objekte wird die Methode remove() aufgerufen, der dann jeweils die ersten beiden Werte übergeben werden. Rufen Sie also beispielsweise $tabelle->removePrimary(1,'id',$tabelle2, $tabell3); auf, werden die Aufrufe $tabelle2->remove(1,'id') und $tabelle3->remove(1,'id') getätigt.

 <<   zurück
     
  Zum Katalog
Zum Katalog: PHP PEAR
PHP PEAR
Jetzt bestellen!
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: PHP 5.6 und MySQL 5.7






 PHP 5.6 und
 MySQL 5.7


Zum Katalog: Einstieg in PHP 5.6 und MySQL 5.6






 Einstieg in PHP 5.6
 und MySQL 5.6


Zum Katalog: Responsive Webdesign






 Responsive Webdesign


Zum Katalog: Moderne Websites entwickeln






 Moderne Websites
 entwickeln


Zum Katalog: MySQL 5.6






 MySQL 5.6


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo








Copyright © Rheinwerk Verlag GmbH 2007
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Rheinwerk Computing]

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de