74
Auf einen Blick Vorwort ..................................................... 11 1 Die Arbeit mit PHP .................................... 13 2 Datentypen und -konvertierung ................ 25 3 Programmierstil ......................................... 49 4 Modularisierung von Code ........................ 91 5 Error-Handling .......................................... 143 6 Professionelle Bibliotheken ....................... 187 7 Qualitätssicherung .................................... 267 8 Dokumentation ......................................... 299 9 Praxis-Lösungen für den Programmieralltag ..................................... 325 Inhalt der CD............................................. 605 Index ......................................................... 607 www.galileocomputing.de - Besser PHP programmieren - Leseprobe

Besser PHP programmieren - Amazon S3...Datentypen in PHP 27 1 2 3 4 5 6 7 8 9 2 Datentypen und -konvertierung If it doesn't fit, use a bigger hammer. – Miles O’Brian, Star Trek

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Auf einen Blick

Vorwort ..................................................... 11

1 Die Arbeit mit PHP.................................... 13

2 Datentypen und -konvertierung................ 25

3 Programmierstil ......................................... 49

4 Modularisierung von Code........................ 91

5 Error-Handling .......................................... 143

6 Professionelle Bibliotheken....................... 187

7 Qualitätssicherung .................................... 267

8 Dokumentation ......................................... 299

9 Praxis-Lösungen für den Programmieralltag ..................................... 325

Inhalt der CD............................................. 605

Index ......................................................... 607

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

I

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

1.1 Lernen Sie Ihr Arbeitsgerät kennen ....................................................... 15

1.2 Der Editor ............................................................................................. 161.2.1 Zend Studio ............................................................................. 17

2.1 Datentypen in PHP ............................................................................... 272.1.1 Boolean ................................................................................... 272.1.2 Integer ..................................................................................... 272.1.3 Float ........................................................................................ 282.1.4 String ....................................................................................... 31

2.2 Typ-Konvertierung ................................................................................ 34

2.3 Arrays .................................................................................................... 37

3.1 HTML in PHP oder PHP in HTML? ........................................................ 52

3.2 Allgemeines zur Programmierung ......................................................... 543.2.1 Verständlichkeit ....................................................................... 553.2.2 Alternative PHP-Syntax ............................................................ 573.2.3 Kommentare ............................................................................ 573.2.4 Vermeiden Sie »Magic Numbers« ............................................. 603.2.5 ToDos, Fallstricke und andere Probleme ................................... 613.2.6 Halten Sie Ordnung .................................................................. 62

3.3 Quelltext-Formatierung ........................................................................ 633.3.1 Globale Struktur ....................................................................... 633.3.2 Klammerung ............................................................................ 643.3.3 Einrückungen ........................................................................... 663.3.4 Verschachtelte Funktionsaufrufe ............................................... 663.3.5 SQL und JavaScript ................................................................... 673.3.6 Komplexe Bedingungen ........................................................... 68

3.4 Namensgebung ..................................................................................... 693.4.1 Abkürzungen ............................................................................ 70

nhalt

Vorwort 11

1 Die Arbeit mit PHP 13

2 Datentypen und -konvertierung 25

3 Programmierstil 49

Inhalt 5

6

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

3.4.2 Namen für Variablen und Konstanten ...................................... 703.4.3 Namen für Funktionen und Klassen ......................................... 73

3.5 Kontrollstrukturen ................................................................................ 753.5.1 Bedingungen ........................................................................... 753.5.2 Fallunterscheidungen ............................................................... 793.5.3 Der ternäre Operator ............................................................... 803.5.4 Die Arbeit mit Schleifen ........................................................... 81

3.6 Is it a bug or is it a feature? .................................................................. 843.6.1 Die Inkrement-Operatoren ...................................................... 843.6.2 Die Funktion empty() .............................................................. 863.6.3 Groß-/Kleinschreibung ............................................................. 873.6.4 Parameter von Funktionen ....................................................... 883.6.5 Neue PHP-Versionen ............................................................... 893.6.6 Undokumentierte Funktionen .................................................. 89

4.1 Arbeiten mit externen Bibliotheken ..................................................... 93

4.2 Funktionen ........................................................................................... 964.2.1 Design von Funktionen und Methoden .................................... 99

4.3 Objektorientierung ............................................................................... 1044.3.1 Zugriff auf Objekte ................................................................... 1064.3.2 Deklaration von Klassen ........................................................... 1074.3.3 Erweiterte objektorientierte Programmiertechniken ................. 1144.3.4 Introspektion ........................................................................... 1204.3.5 OOP-Erweiterungen in PHP 5 .................................................. 126

5.1 Der @-Operator ................................................................................... 150

5.2 Eigene Error-Handler ............................................................................ 1525.2.1 Fehlermanagement .................................................................. 157

5.3 Error-Handling in Bibliotheken ............................................................. 1655.3.1 Error-Handling bei Funktionsbibliotheken ................................ 1655.3.2 Error-Handling in Klassenbibliotheken ..................................... 169

5.4 Exception-Handling in PHP 5 ............................................................... 174

5.5 Fehler-Dokumente ............................................................................... 179

6.1 Smarty .................................................................................................. 1906.1.1 Modifikatoren .......................................................................... 1986.1.2 Funktionen .............................................................................. 2066.1.3 Caching ................................................................................... 213

4 Modularisierung von Code 91

5 Error-Handling 143

6 Professionelle Bibliotheken 187

Inhalt

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

6.2 PEAR ..................................................................................................... 2146.2.1 Installation ............................................................................... 2146.2.2 Nutzung von PEAR ................................................................... 2196.2.3 Fehlerbehandlung in PEAR ....................................................... 2216.2.4 Das Paket DB ........................................................................... 2226.2.5 Authentifizierung mit PEAR ..................................................... 2356.2.6 Paket Spreadsheet_ Excel_Writer .............................................. 2506.2.7 XML_Tree ................................................................................ 260

7.1 Im Vorfeld ............................................................................................. 269

7.2 Qualitätsmerkmale ................................................................................ 270

7.3 Reviews ................................................................................................. 272

7.4 Debugging ............................................................................................ 2737.4.1 PHP-interne Debug-Features .................................................... 2737.4.2 Eigene Debug-Routinen ........................................................... 2807.4.3 Debugging mit PHPUnit ........................................................... 2857.4.4 Professionelle Debugger ........................................................... 289

7.5 Testen ................................................................................................... 2957.5.1 Personal ................................................................................... 2967.5.2 Vorgehensweise ....................................................................... 298

8.1 Anforderungen an eine Dokumentation ................................................ 301

8.2 Programmablaufpläne und Struktogramme .......................................... 305

8.3 phpDocumentor .................................................................................... 3108.3.1 Die wichtigsten Tags ................................................................ 3178.3.2 Kommandozeilenoptionen ....................................................... 322

9.1 Elementare Datenstrukturen und Algorithmen ..................................... 3279.1.1 Mengen ................................................................................... 3279.1.2 Queues .................................................................................... 3299.1.3 Stacks ...................................................................................... 3309.1.4 Verkettete Listen ...................................................................... 3309.1.5 Bäume und Rekursion .............................................................. 331

9.2 Interaktion mit Benutzern ..................................................................... 3439.2.1 Aufbau von Formularen ........................................................... 3439.2.2 Wertübernahme aus Formularen .............................................. 347

7 Qualitätssicherung 267

8 Dokumentation 299

9 Praxis-Lösungen für den Programmieralltag 325

Inhalt 7

8

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

9.2.3 Prüfen von Benutzereingaben .................................................. 3509.2.4 Formulare mit Flash MX ........................................................... 355

9.3 Reguläre Ausdrücke .............................................................................. 3809.3.1 Delimiter ................................................................................. 3819.3.2 Zeichenklassen ......................................................................... 3829.3.3 Quantifier ................................................................................ 3859.3.4 Anker ...................................................................................... 3869.3.5 Submuster ............................................................................... 3879.3.6 Backreferences ......................................................................... 3889.3.7 Lookaround ............................................................................. 3889.3.8 Bedingte Ausdrücke ................................................................. 3919.3.9 Gier ......................................................................................... 3919.3.10 Optionen ................................................................................. 3929.3.11 PCRE-Funktionen .................................................................... 394

9.4 Arbeit mit Dateien ................................................................................ 3999.4.1 Unterschiede bei Dateien ......................................................... 4009.4.2 CSV-Dateien ............................................................................ 4099.4.3 Locks auf Dateien .................................................................... 413

9.5 Mails ..................................................................................................... 4199.5.1 Allgemeines zu Mails ............................................................... 4199.5.2 Empfänger der Mail ................................................................. 4219.5.3 Header-Felder ......................................................................... 4229.5.4 MIME-Mails ............................................................................ 4269.5.5 Anhänge komprimieren ........................................................... 4379.5.6 Mails verschlüsseln .................................................................. 439

9.6 Sicherheit ............................................................................................. 4469.6.1 Fertige Lösungen ..................................................................... 4479.6.2 Sessions ................................................................................... 4489.6.3 Globals .................................................................................... 4529.6.4 Verschiedene Angriffsarten ...................................................... 4589.6.5 Passwörter ............................................................................... 4739.6.6 Altersüberprüfung .................................................................... 4819.6.7 Schutz von E-Mail-Adressen .................................................... 487

9.7 Shared Memory .................................................................................... 491

9.8 Installationsprogramme ........................................................................ 5039.8.1 Installationsvoraussetzungen .................................................... 5049.8.2 Übernahme von Werten .......................................................... 5109.8.3 Konfigurationsdateien .............................................................. 5129.8.4 Installation von Komponenten ................................................. 5159.8.5 Tabellen ................................................................................... 5199.8.6 Serverzeit ................................................................................ 5229.8.7 Grafiken .................................................................................. 5279.8.8 Uninstall .................................................................................. 531

9.9 Internationalisierung/Lokalisierung ...................................................... 5349.9.1 Mehrsprachige Texte ............................................................... 5349.9.2 Datums- und Zahlenformate .................................................... 537

9.10 Performance-Tuning ............................................................................. 5429.10.1 Performance-Bremsen finden ................................................... 547

Inhalt

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

9.10.2 Statische Seiten generieren ....................................................... 5569.10.3 Datenbank-Abfragen ................................................................ 5609.10.4 Cache-Systeme ........................................................................ 568

9.11 Genau rechnen ...................................................................................... 5779.11.1 BCMath ................................................................................... 578

9.12 Arbeit mit Datenbanken ....................................................................... 5809.12.1 Allgemeines ............................................................................. 5809.12.2 Transaktionsorientierung .......................................................... 5899.12.3 PHPMyAdmin .......................................................................... 5929.12.4 ODBC ...................................................................................... 5969.12.5 Volltextsuche in einer MySQL-Datenbank ................................ 601

Inhalt der CD 605

Index 607

Inhalt 9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

Vorwort

Schön, dass Sie zu diesem Buch gegriffen haben. Aber: Noch ein weiteres PHP-Buch? Es gibt doch bereits so viele PHP-Bücher! Grundsätzlich haben Sie Recht,aber es gibt nicht viele Bücher, die wie dieses sind. Sicherlich gibt es viele Ein-führungen in PHP, PHP-Kochbücher oder Bücher, die sich mit speziellen The-men befassen. Leider wird dabei oft vergessen, dass Programmierung nicht nuraus einer Aneinanderreihung von Befehlen besteht. Programmierung heißtauch, Software ordentlich zu entwerfen und sie so zu implementieren, dass siesowohl stabil läuft als auch wartbar bleibt.

Daher bietet Ihnen mein Buch Know-how und Hintergrundinformation zurTheorie des Programmierens und Lösungsansätze für alltägliche Probleme ausder Praxis. Bekanntermaßen ist Theorie nicht sehr beliebt; daher habe ich dieseTeile relativ kurz gehalten – so viel wie erforderlich, so wenig wie nötig. Darü-ber hinaus finden Sie viele grundsätzliche Informationen zum Umgang mitPHP, die selbst erfahrene Programmierer noch nicht kennen. Neben Informa-tionen zu Datentypen und -strukturen, beschreibe ich grundlegende Funk-tionen, die häufig unbekannt sind, sich in der Praxis aber als sehr hilfreicherweisen. So finden Sie neben Erläuterungen zur Objektorientierung (inkl. derneuen PHP 5-Erweiterungen) und grundlegenden Datenstrukturen wie Stacksund Queues auch die vielen Array-Funktionen, die mit PHP 4 eingeführt wur-den und ebenfalls weitgehend unbekannt geblieben sind.

Ein Großteil des Buches zeigt Ihnen Lösungen für tägliche Probleme. Hierbeihandelt es sich nicht um Lösungen die Sie 1 zu 1 übernehmen sollen. Entspre-chend dem Sprichwort »Gib einem Menschen einen Fisch, und er wird füreinen Tag satt. Lehre ihn fischen, und er wird ein Leben lang satt« habe ich dieseexemplarisch vorgestellt. Alles ist an konkreten Beispielen umgesetzt und dierelevanten Quelltexte sind auf der CD enthalten. Ich möchte Sie aber ermuti-gen, auch eigene Lösungswege zu beschreiten. Weiterhin bietet Ihnen diesesBuch Informationen zum Thema Sicherheit, der Kommunikation mit Flash, derArbeit mit Dateien, der Nutzung von PEAR und vielen anderen Themenberei-chen.

Das Buch richtet sich nicht an Anfänger. Es ist für all diejenigen gedacht, diebereits über ein wenig Erfahrung in der PHP-Programmierung verfügen undnun ihr Wissen erweitern wollen. Aber auch diejenigen, die schon seit vielenJahren programmieren, können in diesem Buch sicher fündig werden. Vor die-sem Hintergrund sind die meisten »alltäglichen« Befehle nicht erläutert;komplizierte oder ausgefallenere Befehle werden natürlich vorgestellt underklärt.

Vorwort 11

12

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

Die meisten Programmierer, die ich kenne – und ich bilde da keine Ausnahme– neigen dazu ein Buch nicht komplett lesen zu wollen. Daher ist dieses Buchauch nicht so konzipiert, dass Sie es von vorne bis hinten durchlesen müssen.Natürlich können Sie dies tun, aber die Kapitel bilden in sich abgeschlosseneEinheiten. Somit können Sie das Werk auch zum Nachschlagen benutzen odernur die Kapitel lesen, die Sie benötigen. Wenn Sie sich noch nicht mit demThema Objektorientierung beschäftigt haben, empfehle ich Ihnen, dass SieKapitel 4.3 auf jeden Fall lesen.

Ich hoffe, dass Sie beim Lesen des Buches nicht nur Spaß haben, sondern dasses Ihnen möglichst viel Nutzen bringt.

Sollten Sie Fragen, Anmerkungen oder Verbesserungsvorschläge haben, schrei-ben Sie einfach eine kurze E-Mail an: [email protected]

Bielefeld, den 10.03.2004Carsten Möhrke

Vorwort

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

2 Datentypen und -konvertierung

If it doesn't fit, use a bigger hammer.– Miles O’Brian, Star Trek

2.1 Datentypen in PHP

Im Gegensatz zu vielen anderen Programmiersprachen unterstützt PHP leiderkeine Variablendeklaration, und der Programmierer hat auch nicht die Möglich-keit, einer Variable einen Typ zuzuweisen. PHP ermittelt selbst, welchen Typeine Variable haben muss und führt ein automatisches »Type Casting« durch.Das heißt, eine Variable kann automatisch von einem Typ in einen anderenkonvertiert werden. Das führt dazu, dass viele Entwickler sich keine Gedankenüber den Datentyp machen. Frei nach dem Motto »PHP wird's schon richten«gehen sie davon aus, dass die Konvertierung automatisch erfolgt und keineunangenehmen Nebeneffekte haben wird. Leider ist das nicht immer so.

PHP kennt vier skalare Datentypen:

� Boolean

� Integer

� Float

� String

2.1.1 Boolean

Bei Boolean handelt es sich um einen Datentyp, der nur zwei Werte unterstützt.Hierbei handelt es sich um true (wahr) und false (falsch). Häufig wird truemit dem Wert 1 und false mit dem Wert 0 gleichgesetzt, was so aber nicht kor-rekt ist. Wird ein Boolescher Wert in einer Berechnung genutzt, konvertiertPHP ein true allerdings in 1 und false in 0. Das funktioniert natürlich auch indie andere Richtung. Die Zahl 0 kann in ein false konvertiert werden, wohin-gegen alle anderen Werte als true interpretiert werden. Boolesche Werte wer-den häufig als Rückgabewerte von Funktionen genutzt.

2.1.2 Integer

Bei dem Datentyp Integer handelt es sich um ganzzahlige Werte, also Zahlenohne einen Nachkommaanteil. Ein Integer-Wert kann typischerweise zwischen–2147483648 und 2147483647 liegen. Leider ist das aber nicht präzise vor-hersagbar, da dieser Wertebereich vom verwendeten Betriebssystem bzw.

Datentypen in PHP 27

28

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

C-Compiler abhängt. Normalerweise wird der genannte Bereich aber ohne Pro-bleme unterstützt. Beachten Sie, dass der Wertebereich im negativen Bereichum eins größer ist als im positiven.

Bei der Wertzuweisung sollten Sie beachten, dass PHP auch das hexadezimaleund das oktale Zahlensystem unterstützt. Eine Zahl, die mit einer 0 beginnt,wird als oktal gewertet, und ein Wert, der mit einem 0x beginnt, als hexadezi-male Zahl. Dies kann schnell zu einem unerwarteten Verhalten führen:

$oktal=0815; // beliebte Zahl zum Testenecho $oktal; // gibt 0 aus, da 8 keine gültige oktale Zahl ist

$oktal2=042; // auch eine beliebte Zahlecho $oktal2; // gibt 34 aus

$hex=0x11;echo $hex; // gibt 17 aus

Achten Sie also auch bei Werten, die Sie »nur mal gerade zum Testen« eingeben,sehr genau darauf, dass Sie nicht mit einer führenden Null arbeiten.

2.1.3 Float

Float-Werte sind Fließkommazahlen, sie unterstützen also einen Nachkomma-anteil. Eine Unterscheidung zwischen Fließkommazahlen mit einfacher unddoppelter Genauigkeit ist in PHP nicht vorgesehen. Auch wenn dieser Datentypin PHP als float bezeichnet wird, so basiert er doch auch dem Datentyp doubledes verwendeten C-Compilers. Der verfügbare Wertebereich entspricht somitauch dem, den das Betriebssystem bzw. der C-Compiler für double unterstützt.Typischerweise ist das der Bereich von 1,7e-308 bis 1,7e+308. Die Genauigkeitbeträgt hierbei 15 Stellen.

Vergleicht man die hier beschriebenen Eigenschaften der Datentypen Integerund Float, könnte man auf die Idee kommen, immer nur mit Fließkomma-zahlen zu arbeiten. Leider sind diese aber sehr ungenau, so dass man sie, wennmöglich, vermeiden sollte.

$float=0.3;$float+=0.3;$float+=0.3;$float+=0.1;echo ("\$float: $float <br />");echo ("floor() liefert:".floor($float));

Listing 2.1 Ungenauigkeit bei Fließkommaoperationen

Datentypen und -konvertierung

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

So generiert dieses kleine Programm nicht wie erwartet 1 und 1 als Ausgabe,sondern:

$float:1floor() liefert:0

Dieses Verhalten ist üblicherweise auch recht einfach mit einer for-Schleifenachzuweisen. So rechnet diese Schleife

for ($counter=0; $counter<1000; $counter+=0.01){

echo ("$counter <br />");}

grundsätzlich korrekt. Unter PHP 4.2.3 (Linux, Float-Genauigkeit 14 Stellen)finden sich allerdings folgende Zwischenergebnisse:

4.424.4299999999999…9.11999999999999.1299999999998…9.999999999999810.01…

PHP 4.3.3 (Linux, Float-Genauigkeit 12 Stellen) rechnet länger korrekt. Hiertritt der Rechenfehler erst bei 709.25 auf:

709.25709.259999999

PHP 5 kommt unter Windows bei einer Float-Genauigkeit von 12 Stellen erstein wenig später zu einem falschen Ergebnis:

709.26709.269999999

Wie Sie sehen, ist das Ergebnis einer Fließkomma-Operation nicht immer kor-rekt. Das ist leider auch nicht zu verhindern, da das Problem darin begründetist, wie Fließkommazahlen abgespeichert werden. Die Frage ist also nicht, obein Rechenfehler, sondern wann er auftritt. Er wird auf jeden Fall da sein. Fließ-kommazahlen sollten also nicht für finanztechnische Operationen eingesetztwerden. Bei anderen Problemen, wie statistischen Berechnungen etc., machtsich ein solcher Rechenfehler häufig nicht dramatisch bemerkbar. Solche

Datentypen in PHP 29

30

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

Rechenfehler können Sie nur durch den Einsatz anderer Datentypen oder derBCMath-Funktionen verhindern.

Bitte lassen Sie sich nicht dadurch täuschen, dass in der Konfigurationsdateiphp.ini mit Hilfe der Direktive precision= eine Fließkommagenauigkeit ange-geben werden kann. In vielen Fällen gehen Programmierer davon aus, dass eineGenauigkeit von 14 Stellen das oben gezeigte Verhalten verhindert. Leider istdas aber nicht so. Sie bekommen das ungenaue Ergebnis nur mit ein paar Stel-len mehr ausgegeben.

Ein weiterer wichtiger Punkt ist, dass Sie eine Fließkommazahl nicht direkt auseinem Formular übernehmen und damit rechnen sollten. So könnte die Zahl13421,45 in verschiedenen Notationen eingegeben werden. Ein Program-mierer gibt wahrscheinlich 13421.45 ein, da er weiß, wie ein Fließkommawertzu notieren ist. Ein deutscher Buchhalter würde u. U. 13.421,45 eingeben undden Punkt als Tausendertrennzeichen nutzen. Ein amerikanischer Buchhalterkönnte hingegen folgende Schreibweise bevorzugen: 13,421.45. Folgendeskleines Programm zeigt Ihnen die Resultate unterschiedlicher Eingaben:

$am_avg="13421.45"; // "Durchschnittlicher" Amerikaner$am_act="13,421.45"; // Amerikanischer Buchhalter$de_avg="13421,45"; // "Durchschnittlicher" Deutscher$de_act="13.421,45"; // Deutscher Buchhalter

echo "\"Durchschnittlicher\" Amerikaner: ".(1.0*$am_avg);echo "<br />Amerikanischer Buchhalter: ".(1.0*$am_act);echo "<br />\"Durchschnittlicher\" Deutscher: ".(1.0*$de_avg);echo "<br />Deutscher Buchhalter: ".(1.0*$de_act);

Listing 2.2 Unterschiedliches Eingabeverhalten

Die Ausgabe dieses Codes sieht folgendermaßen aus:

"Durchschnittlicher" Amerikaner: 13421.45Amerikanischer Buchhalter: 13"Durchschnittlicher" Deutscher: 13421Deutscher Buchhalter: 13.421

Sie sehen, dass »ähnliche« Eingaben zu einem deutlich unterschiedlichenErgebnis führen. Wenn Sie also Floats aus einer externen Datenquelle einlesen,müssen Sie die Validität der Werte sehr genau prüfen bzw. die Werte konver-tieren.

Häufig wird das Problem der Zahlendarstellung bzw. des »Verrechnens« unter-schätzt. Bei genauer Betrachtung verrechnen sich erstaunlich viele Applika-

Datentypen und -konvertierung

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

tionen. In Abbildung 2.1 sehen Sie einen Finanzierungsrechner einer renom-mierten Bank, der mit seiner eigenen Zahlendarstellung durcheinander kam.Korrekt wäre eine monatliche Rate von 589,10 € gewesen.

Abbildung 2.1 Ein Finanzierungsrechner, der sich verrechnet

2.1.4 String

Der letzte elementare Datentyp ist der String, also ein Text. Die maximale Längevon Strings ist in PHP nicht begrenzt. Natürlich kann ein Computer nichts ver-arbeiten, was unendlich groß ist, aber für die meisten Anwendungen sollten dieMöglichkeiten von PHP ausreichen1. Erfahrungsgemäß stellen aber auch sehrlange Texte von einigen Mega-Byte Größe kein Problem dar.

Strings sind in PHP recht einfach zu handhaben, aber einige kleinere Punktesollten Sie beachten. Weisen Sie einer Variablen einen Wert zu, können Sie ihnin doppelte ("") oder einfache ('') Anführungszeichen einschließen. Diese Zei-chen werden in der englischsprachigen Literatur auch gern als Ticks (einfacheAnführungszeichen) oder als double Ticks (doppelte Anführungszeichen)bezeichnet. Bei einer Wertzuweisung mit doppelten Anführungszeichen wer-den enthaltene Variablen ausgewertet und ihr Wert eingefügt. Bei einfachenAnführungszeichen erfolgt diese Konvertierung nicht.

1 Leider ist das PHP-Manual hier nicht sehr präzise. Zitat: »It is no problem for a string tobecome very large. There is no practical bound to the size of strings imposed by PHP, sothere is no reason at all to worry about long strings.«

Datentypen in PHP 31

32

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

$a="Hallo Welt!";$b="$a"; // doppelte Anführungszeichen; wird konvertiert$c='$a'; // einfache Anführungszeichen; wird nicht konvertiertecho $b; //gibt Hallo Welt ausecho $c; // gibt $a aus

Manchmal kommt es vor, dass Sie den Variablennamen nicht ohne Problemevom nachfolgenden Text abgrenzen können. Nehmen wir an, dass in der Varia-ble z.B. der Text »rot« enthalten ist und Sie »Ich habe einen roten Apfel« aus-geben lassen wollen, wobei das »roten« natürlich mit Hilfe der Variable gene-riert werden soll. In diesem Fall können Sie den String in einzelne Teilezerlegen und diese mit Hilfe des Verknüpfungsoperators mit der Variable zu-sammenfügen. Die zweite Möglichkeit ist, den Variablennamen in geschweifteKlammern zu setzen.

$farbe="rot";$a="Ich habe einen $farbeen Apfel<br />";$b="Ich habe einen ".$farbe."en Apfel<br />";$c="Ich habe einen ${farbe}en Apfel<br />";echo $a,$b,$c;

Listing 2.3 Ausgabe von String mit Hilfe der geschweiften Klammer

Diese Zeilen generieren folgende Ausgabe:

Ich habe einen ApfelIch habe einen roten ApfelIch habe einen roten Apfel

Die erste Variante liefert nicht das gewünschte Ergebnis, da PHP versucht, aufeine Variable $farbeen zuzugreifen, die aber nicht deklariert ist. Der Wert für$b wird mit Hilfe des Verknüpfungsoperators erstellt. Die letzte Variante basiertauf der »einfachen geschweiften Syntax«. Dadurch, dass der Variablenname ingeschweifte Klammern gesetzt ist, kann der Parser ihn eindeutig identifizieren.

Bei längeren Strings, insbesondere dann, wenn Sie diese aus einer anderenQuelle herauskopieren, kann es recht umständlich sein, den String mit Anfüh-rungszeichen einzuschließen. Alle im Text enthaltenen Anführungszeichenmüssten entwertet werden. In einem solchen Zusammenhang empfiehlt sichdie heredoc-Syntax. Bei ihr wird der zu verarbeitende Text in spezielle »Schlüs-selwörter« eingeschlossen.

<?php$a="PHP";

Datentypen und -konvertierung

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

$b= <<<STRINGENDEIn diesemBuch geht's um"$a"

STRINGENDE;

echo $b; // Ausgabe: In diesem Buch geht's um "PHP"?>

Der Variable $b wird der Wert mit Hilfe der heredoc-Syntax zugewiesen. Ein-geleitet wird das String-Literal mit <<<STRINGENDE, wobei STRINGENDE ein freigewählter Bezeichner ist. Der Parser legt den gesamten nachfolgenden Text ab,bis er wieder STRINGENDE findet. Wichtig ist, dass das schließende Token direktam Anfang der Zeile stehen muss. Es darf also kein Leerzeichen, kein Tabulator-schritt o. Ä. davor zu finden sein. Innerhalb eines heredoc-Bereichs müssenAnführungszeichen, im Gegensatz zu anderen Sonderzeichen, nicht entwertetwerden. Bei einer solchen Wertübergabe werden auch die Zeilenumbrüche mitin der Variablen abgelegt.

Möchten Sie auf einzelne Zeichen innerhalb eines Strings zugreifen, so müssenSie keine aufwändigen Stringfunktionen nutzen. Sie können auf die einzelnenZeichen quasi wie auf Array-Elemente zugreifen, wobei die Syntax etwas andersist. Anstelle der eckigen werden hier geschweifte Klammern verwendet.

$str="Hallo";echo $str{0}; // gibt H ausecho $str{4}; // gibt o aus

Dass Sie mit dem Backslash Zeichen entwerten können bzw. »Whitespaces« wieTabulatoren und Zeilenumbrüche ausgeben können, ist Ihnen sicher bekannt.

Zeichenfolge Ausgabe / Erläuterung

\n Zeilenvorschub (LF, ASCII-Code 10dez)

\r Wagenrücklauf (CR, ASCII-Code 13dez)

\t Horizontaler Tabulator (HT, ASCII-Code 9dez)

\\ Backslash

\$ Dollar-Symbol

\” Doppelte Anführungszeichen

\0 – \777 ASCII-Code des auszugebenden Zeichens in oktaler Schreibweise

\x0 – \xFF ASCII-Code des auszugebenden Zeichens in hexadezimaler Schreibweise

Datentypen in PHP 33

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

3.4 Namensgebung

Quelltexte sind deutlich besser zu verstehen, wenn Programmierer sich an einvereinheitlichtes Namensschema halten. Variablennamen wie $a oder $i sindnicht akzeptabel. Selbst bei trivialen Konstrukten wie einer kleinen for-Schleifesollten Sie sich nicht zu solchen Bezeichnern hinreißen lassen.

for ($i=0; $i < 10; $i++){

$j=$i*$i;echo ("$i * $i = $j");

}

ist sicher nicht so deutlich wie:

for ($zaehler=0; $ zaehler < 10; $ zaehler ++){

$quadrat=$zaehler * $zaehler;echo ("$zaehler * $ zaehler = $quadrat");

}

Um ein allgemein verständliches Schema zu entwickeln, müssen sich natürlichalle an einem Projekt Beteiligten an einen gemeinsamen Standard halten. Lei-der gibt es in der Programmierung kein fest definiertes Schema, das ich hiererläutern könnte. Es gibt nur viele unterschiedliche Ansätze, aus denen ich dieinteressantesten Ansätze extrahiert habe.

Grundsätzlich gilt, dass ein Name aussagekräftig, allgemein verständlich undnicht zu lang sein sollte. Anhand des Namens sollte sofort zu erkennen sein,wozu eine Funktion oder Variable dient. Die Gratwanderung zwischen einemzu kurzen, unverständlichen und einem zu langen, umständlichen Namen istnicht einfach. Arbeiten Sie mit Abkürzungen, wo es nötig ist, aber sein Sie auchnicht zu tippfaul.

Eines möchte ich noch vorwegschicken: Es passiert immer mal wieder, dass einProgramm nicht läuft oder eine Funktion etwas komplett anderes macht alserwartet. Die meisten von Ihnen werden das schon erlebt haben. So etwasresultiert immer mal wieder daraus, dass Sie zufällig einen Variablen- oderFunktionsnamen genutzt haben, der auch in PHP intern oder in zusätzlich ein-gebundenen Bibliotheken genutzt wird. Sie müssen bei Ihrer Namenswahlimmer auf der Hut sein, dass es nicht zu einer »Bezeichner-Kollision« kommt.Bei Code, der nicht für eine internationale Zielgruppe bestimmt ist, könnte manbeispielsweise über Bezeichner in deutscher Sprache nachdenken, oder Siekönnten die Bezeichner jeweils mit ein Prä- oder Suffix versehen, das nur Sie

Namensgebung 69

70

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

nutzen. Des Weiteren sollten Sie Bezeichner vermeiden, die mit einem Unter-strich beginnen, da dieser häufig als Präfix für PHP-interne Namen (z.B. $_POSTetc.) genutzt wird.

3.4.1 Abkürzungen

Bei der Vergabe von Namen für beliebige Objekte wird häufig mit Abkür-zungen gearbeitet. Grundsätzlich sollten Sie Abkürzungen vermeiden, aber ichdenke, dass sie einen großen Vorteil mit sich bringen: Sie sind kürzer. Sicherliegt das in der Natur einer Abkürzung, aber das, worauf ich hinaus möchte, ist,dass Befehlzeilen deutlich kürzer werden und sich dadurch die Lesbarkeit ver-bessert. Denken Sie z.B. an den Kopf einer for-Schleife. Hier kommt der Nameeiner Variable mehrfach vor, und die Länge der einzelnen Bezeichner addiertsich dann schnell zu einer Zeile, die umbrochen werden muss.

for ($aktueller_index=0; $aktueller_index<10; $aktueller_index++)//...

Vor diesem Hintergrund sind Abkürzungen sicher akzeptabel. Die Kunstbesteht nur darin, richtig abzukürzen. Grundsätzlich können Sie sich an fol-gendes Schema halten: Streichen Sie aus dem abzukürzenden Wort alle Vokaleheraus. Von den verbleibenden Konsonanten werden alle entfernt, die doppeltoder nicht betont sind. Häufig erhalten Sie dann schon eine brauchbare Abkür-zung.

Hier einige Beispiele:

Wie gesagt sollten Sie Abkürzungen mit Bedacht einsetzen. Wenn Sie sie nut-zen, dann dokumentieren Sie bitte, was die Abkürzungen bedeuten.

3.4.2 Namen für Variablen und Konstanten

Um im Quelltext erkennen zu können, ob es sich um eine Variable oder eineKonstante handelt, hat es sich durchgesetzt, die Namen von Konstanten kom-plett in Großbuchstaben zu schreiben. Einzelne Wörter innerhalb desBezeichners werden jeweils durch Unterstriche voneinander getrennt.

Abkürzung Bedeutung

crnt current

std Standard

cmd Command

Tabelle 3.1 Beispiele für Abkürzungen

Programmierstil

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

define ("MWST",0.16);define ("DSTNZ_MOND_ERDE",384000 );

Für Variablen gibt es allerdings schon ein wenig mehr zu beachten, was einfachdaran liegt, dass Variablen in unterschiedlichsten Zusammenhängen zu findensind. Grundsätzlich gilt, dass Variablen komplett in Kleinbuchstaben geschrie-ben werden. Einzelne Wörter innerhalb des Bezeichners werden auch hier miteinem Unterstrich voneinander getrennt. Das kann beispielsweise so aussehen:

$aktuelle_summe=$aktuelle_summe+$einzelpreis_artikel;$anzahl_positionen+=1;

Wie schon erwähnt, tauchen Variablen aber in unterschiedlichsten Zusammen-hängen auf. Neben den »normalen« Varianten gibt es noch Referenzen aufVariablen, globale und statische Variablen. Und gerade hierbei ist es sehr wich-tig, nicht den Überblick zu verlieren. Um dies zu vereinfachen, sollten Sie denNamen von Referenzen ein r und denen von global verwendeten Variablen eing voranstellen. Statische Variablen, die man nur einsetzen sollte, wenn es dennwirklich notwendig ist, werden um das Präfix s ergänzt.

$g_akt_summe=0.0; //aktuelle Summe aller Einzelpreise$lagerbestand=10; // Aktueller Lagerbestand

function artikel_in_warenkorb ($preis, & $r_lagerbestand){

global $g_akt_summe;static $s_anzahl_zugriffe=0; // Zaehlt die Zugriffe

// auf den Warenkorb$s_anzahl_zugriffe++;$g_akt_summe=$g_akt_summe+$preis;$r_lagerbestand=$r_lagerbestand-1;return true;

}

artikel_in_warenkorb(10,$lagerbestand);echo ("Gesamtpreis: $g_akt_summe"); // gibt 10 ausecho ("Lagerbestand: $lagerbestand"); // gibt 9 aus

Listing 3.6 Namensgebung bei globalen und statischen Variablen

Der Variable $g_aktuelle_summe können Sie jederzeit »ansehen«, dass ihrInhalt durch Funktionen manipuliert wird. Bei $lagerbestand ist das nicht so,was aber auch nicht weiter schlimm ist. Wird der Inhalt einer Variable via Refe-renz manipuliert, so wurde sie ja vorher an eine Funktion übergeben, und esist somit recht offensichtlich, dass sie manipuliert wurde.

Namensgebung 71

72

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

Ungarische Notation

Im C- und C++-Umfeld hat sich die »ungarische Notation« durchgesetzt. Siewurde bereits 1972 von Charles Simonyi entwickelt und dient primär dazu,direkt am Variablennamen erkennen zu können, von welchem Typ eine Varia-ble ist. Ein Variablenname wie str_name würde beispielsweise darauf hin-weisen, dass die Variable vom Typ String ist. Da Sie in PHP einer Variable aber(leider) einen Typ nicht eindeutig zuweisen können, hat sich die ungarischeNotation in diesem Umfeld nicht durchgesetzt.

Nichtsdestotrotz möchte ich Sie ermutigen, an den Stellen, an denen der Daten-typ einer Variable wichtig ist, das mit Hilfe eines Präfixes zum Ausdruck zubringen. Dies könnte beispielsweise dann der Fall sein, wenn eine Funktioneinen Integer-Wert erwartet, um bei einer Berechnung die Ungenauigkeiteneiner Fließkomma-Operation zu vermeiden. Tabelle 3.2 stellt einige Präfixe dar,die hilfreich sein können:

Diese Präfixe können Sie natürlich auch noch kombinieren. Wenn Sie z.B. einArray benennen möchten, das aus Fließkommawerten besteht, könnten Sie denVariablennamen mit $arr_f_ einleiten.

Qualifier

Inhalte von Variablen müssen teilweise in bestimmten Wert- oder Maßsyste-men vorliegen. So kann es z.B. sein, dass eine Entfernung in Metern anzugebenist oder eine Zeitangabe nicht in Stunden und Minuten, sondern in Sekundenerfolgen muss. Auch wenn Sie die Deklaration der Variable entsprechendkommentiert haben, so kann es doch hilfreich sein, die Variable mit einemzusätzlichen »Qualifier« zu versehen. Dieser ist Teil des Variablennamens undstellt einen Hinweis auf die Maßeinheit oder den Zustand der Variable dar.

Präfix Erläuterung

str_ Datentyp String

i_ Datentyp Integer

f_ Datentyp Float

b_ Datentyp Bool

arr_ Datentyp Array

obj_ Datentyp Objekt

Tabelle 3.2 Mögliche Präfixe für Variablennamen

Programmierstil

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

3.4.3 Namen für Funktionen und Klassen

Die Namen von Funktionen setzen sich traditionell auch nur aus Kleinbuch-staben und dem Unterstrich zusammen. Auch hierbei gilt natürlich, dass derName der Funktion beschreiben sollte, was sie tut. Sie sollten sich bemühen,die Funktionsnamen kurz, aber ausreichend präzise zu halten. Zu lange Funk-tionsnamen sind verwirrend und zu kurze unter Umständen nicht ausreichendaussagekräftig. Wollten Sie eine Funktion erstellen, die die Summe aller Einzel-preise berechnet, gäbe es verschiedene Möglichkeiten, die Funktion zubenennen. Der Name einzelpreissumme() würde nicht erläutern, dass dieSumme erst von der Funktion gebildet wird. bilde_summe_aller_einzelpreise_und_gib_sie_zurueck() beschreibt zwar alles, was die Funk-tion leistet, ist aber viel zu lang. Ich denke, dass einzelpreise_summieren()eine ganz brauchbare Variante ist. Der Name ist ähnlich kurz wie die ersteVariante, beinhaltet aber die Information, dass die Daten von der Funktion erstaufsummiert werden. An dieser Stelle möchte ich nicht verschweigen, dasseinige Entwickler zwischen Variablen und Parametern unterscheiden und diesenach unterschiedlichen Schemata benennen. Da es aber in den Gültigkeits-bereichen von funktionsinternen Parametern und Variablen, die in einem ande-ren Kontext verwendet werden, keine Überschneidung gibt, denke ich, dasseine noch feinere Untergliederung die Lesbarkeit nicht verbessert.

Klassen bekommen Namen, die sich aus Groß- und Kleinbuchstaben zu-sammensetzen. Üblicherweise lehnt die Namensgebung sich hier an das in Javagenutzte Schema an. Der Name beginnt mit einem Kleinbuchstaben. Jedes neueWort schließt sich direkt an und wird mit einem Großbuchstaben eingeleitet.Der Rest des Wortes wird kleingeschrieben – auch wenn das »Wort« eine Ab-kürzung wie HTML ist. Eine Untergliederung mit Hilfe des Unterstrichs ist nichtüblich. So wäre getHtmlData ein ordentlicher Name, wohingegen man beigetHTMLData nicht sofort identifizieren könnte, wo ein neues Wort beginnt,und Get_Html_Data schnell mit einer Funktion oder einer Variable verwechseltwerden könnte.

Variable Bedeutung

$time_tmstmp Zeitangabe als Timestamp

$time_tmstmp_ms Zeitangabe als Timestamp in Millisekunden

$preis_eur Preisangabe in Euro

$preis_eur_brutto Bruttopreis in Euro

Namensgebung 73

74

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

Diese Vorgehensweise wird auch für die Methoden genutzt, die in der Klasseenthalten sind. Hierbei gilt nicht das für Funktionen übliche Schema, was auchnicht möglich wäre, da zumindest der Konstruktor ja denselben Namen habenmuss wie die Klasse. Wenn Sie in Ihrer Klasse Methoden nutzen, die nur zurinternen Verwendung gedacht sind (auch private Methoden oder Member-Methoden genannt), hat es sich eingebürgert, die Namen mit einem Unterstrich(Underscore) beginnen zu lassen. Ich möchte Sie an dieser Stelle allerdings dazuermutigen, sich von diesem Schema zu lösen. Der Grund ist darin zu sehen,dass in Klassen, auf die Sie aufbauen, schon eine private Methode mit diesemNamen vorhanden sein könnte. Da diese Methoden aber nicht von außen auf-gerufen werden sollen, werden sie häufig nicht dokumentiert und Sie über-schreiben unbemerkt eine notwendige Funktion. Ich würde empfehlen, statt-dessen ein m_ für Member voranzustellen.

Auch Attribute bzw. Eigenschaften einer Klasse kann man recht elegant durchein vorangestelltes m_ kenntlich machen. Das bietet sich allerdings primär dannan, wenn die Eigenschaften nicht direkt von außen, sondern mit Hilfe vonMethoden manipuliert werden sollen.

class shpCart{

var $m_artikelliste; // Array zum Speichern// der Artikelnummern

var $m_gesamtpreis; // enthaelt den aktuellen// Gesamtpreis aller Artikel

function shpCart(){

$this->m_artikelliste=array();}

function artikelHinzufuegen ($artikel_nr, $preis){

array_push($this->m_artikelliste, $artikel_nr);$this->m_gesamtpreis +=$preis;return true;

}

function cartInhalt(){

if (0 < count($this->m_artikelliste))

Programmierstil

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

{return $this->m_artikelliste;

}else{

return false;}

}}

3.5 Kontrollstrukturen

Kontrollstrukturen wie if, while etc. sind elementare Bestandteile einer jedenProgrammiersprache und sollten möglichst gezielt eingesetzt werden.

3.5.1 Bedingungen

Jede Kontrollstruktur benötigt eine Bedingung. Diese Bedingungen werdendazu genutzt, das Verhalten einer Struktur zu steuern. Um einen möglichstzuverlässigen Code zu erstellen, gibt es aber auch hierbei einige Dinge zubeachten.

Wird in einer Bedingung eine Variable mit einer Konstante verglichen, solltedie Konstante immer auf der linken Seite des Vergleichsoperators stehen.Gerade bei einer Prüfung auf Gleichheit kann das Vergessen eines Gleichheits-zeichens sonst fatale Auswirkungen haben.

if ($wert=5) // hier sollte == stehen{

echo ("Alles OK");}else{

echo ("Schwerer Fehler");}

Die Bedingung dieser if-Abfrage wird immer mit true bewertet, da die Varia-ble links steht und der Zuweisungsoperator linksassoziativ arbeitet. Das heißt,bei jeder Abfrage wird $wert der Wert 5 zugewiesen, der auch gleichzeitig vomZuweisungsoperator als Ergebnis der Operation zurückgegeben wird. Da das ifdie 5 als true interpretiert, kann diese Bedingung nie mit false bewertet wer-den. Zusätzlich wird auch noch der Wert der Variablen verfälscht. Sobald Sie dieKonstante aber auf der linken Seite platzieren, liefert der Interpreter Ihnen eine

Kontrollstrukturen 75

190

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

Mitglieder Sie fragen können. Für die meisten Anwendungen gibt es Mailing-listen oder Diskussionsforen, in denen Ihre Fragen schnell geklärt werden.

Aus der Vielzahl der verfügbaren Anwendungen sollen hier zwei vorgestelltwerden. Zum Ersten ist dies Smarty – eine Template-Engine – und zum ZweitenPEAR – eine Funktionsbibliothek. Diese beiden Projekte sollen nur als Beispielevorgestellt werden und Ihnen einen Einstieg in die Materie vermitteln.

6.1 Smarty

Smarty ist – wie schon erwähnt – eine »Template-Engine«. Da nicht jeder vonIhnen wird auf Anhieb wissen wird, was eine Template-Engine ist, möchte iches kurz erläutern.

Einer der Hauptanwendungsbereiche von PHP und vergleichbaren Techno-logien ist die Erstellung von Content Management-Systemen (CMS). Wenn manden Begriff Content Management-System etwas allgemeiner betrachtet, so gehtes einfach nur darum, Content (meist Texte) zu managen, also zu verwalten. DieIdee dahinter ist, dass ein »normaler Mitarbeiter« Texte in das System eintippenkann, die dann automatisch formatiert und für das Ausgabemedium (normaler-weise das Internet) aufbereitet werden. Es sind also keine HTML-Kenntnissenotwendig, um die Website zu aktualisieren. Zusätzlich sind in einem CMS teil-weise noch administrative Funktionalitäten (Genehmigung vom Chefredakteurholen etc.) vorgesehen.

Große CMS kommen beispielsweise bei Zeitungen oder großen Unternehmenzum Einsatz. Auf Websites von kleineren Firmen werden entsprechende Sys-teme genutzt, um News-Seiten aktuell zu halten, und das Gästebuch auf einerprivaten Homepage ist im Endeffekt auch ein CMS. Die wenigsten Webseitenkommen heutzutage also ohne ein CMS aus.

Der Text, den ein solches System verwaltet, wird also automatisch formatiert.Dies erfolgt mit Hilfe von so genannten Templates. Bei Templates handelt essich um Formatvorlagen, die den Text in das gewünschte Layout bringen. Ausdieser Vorgehensweise resultiert also eine Zweiteilung. Zum einen ist da dieApplikationslogik, die für die Speicherung und Verwaltung der Daten zuständigist. Zum anderen gibt es die Templates, die für die Formatierung und somit fürdas Erscheinungsbild der Website verantwortlich sind. Ich möchte zwar nie-mandem zu nahe treten, aber erfahrungsgemäß sind gute Programmierer meistschlechte Designer und gute Designer schlechte Programmierer1. In diesem Fallist das aber kein Problem. Der Programmierer entwickelt das eigentliche CMS,

1 Sollte ich Ihnen mit der Aussage Unrecht tun, so bitte ich um Entschuldigung.

Professionelle Bibliotheken

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

und der Designer kann die Templates designen. Darüber hinaus bietet dieseKonstruktion auch den Vorteil, dass das Design jederzeit geändert werdenkann, ohne dass ein Programmierer bemüht werden muss.

Was hat das alles jetzt aber mit Smarty zu tun? Ganz einfach – Smarty bietetIhnen komfortable, flexible Möglichkeiten, um Templates zu erstellen, und dieApplikationslogik vom Layout zu trennen. Wenn Sie schon mal ein CMS entwi-ckelt haben, dann werden Sie festgestellt haben, wie viel Aufwand es macht,unterschiedliche Texte ansprechend zu formatieren. Smarty bietet wirklich eineganze Menge sehr hilfreicher Funktionalitäten.

Lassen Sie uns einen kurzen Blick darauf werfen, wie das Ganze funktioniert.

Abbildung 6.1 Smartys Funktionsprinzip

Bevor Sie loslegen können, müssen Sie Smarty installieren. Die jeweils aktuelleVersion finden Sie auf der Homepage des Projekts http://smarty.php.net. Fol-gen Sie einfach dem Link »download«, und laden Sie die entsprechende Versionherunter. Am besten wählen Sie den »Latest Stable Release«. Alle anderen Ver-sionen sind entweder veraltet oder so neu, dass sie noch Fehler enthalten könn-ten.

Momentan wird Smarty nur als gezippter Tar-Ball angeboten. Unter Windowsentpacken Sie die Daten am einfachsten mit WinZip2 oder WinRAR3. Sollten Sie

2 Eine 21-Tage-Testversion können Sie unter www.winzip.com herunterladen.3 Eine 40-Tage-Testversion können Sie unter www.rarlab.com herunterladen.

PHP-DateiManagt den Zugriff

auf Datenbanken etc.und bereitet die Daten

für Smarty vor

Datenbank,Dateisystemoder andereDatenquellen

Template-DateiEnthält Anweisungen

zur Formatierungder Daten

Fertige HTML-Seite

Smarty 191

192

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

die Datei auf einem UNIX/Linux-System abgelegt haben, so können Sie diesemit den Befehlen

gunzip Smarty.2.5.0.tar.gztar -xf Smarty.2.5.0.tar

entpacken.

Smarty bringt eine ganze Menge Dateien mit, die Sie nicht unbedingt brauchen.Alles, was Sie benötigen, ist unterhalb des Verzeichnisses /libs/ zu finden. DasUnterverzeichnis können Sie (inklusive aller Dateien und Unterverzeichnisse)an einen beliebigen Ort verschieben. Wichtig ist nur, dass der Webserver Lese-rechte auf das Verzeichnis hat. Unter Windows müssen Sie sich keine weiterenGedanken darüber machen, bei UNIX sieht das allerdings anders aus. Smartybenötigt Leserechte auf die Dateien und Verzeichnisse. Zusätzlich muss derBenutzer, unter dem der Webserver ausgeführt wird, noch das Execute-Rechtfür das Smarty-Unterverzeichnis besitzen. Die Smarty-Dateien müssen nichtunterhalb des DocumentRoot-Verzeichnisses des Webservers liegen.

Um alle Features von Smarty nutzen zu können, brauchen Sie aber noch drei,besser vier weitere Verzeichnisse.

Hierbei handelt es sich um:

� templates

� configs

� templates_c

� cache

Die Namen der Verzeichnisse sind nicht zwingend vorgegeben, Sie könnten sieauch anders benennen. Die nachfolgenden Verzeichnisse legen Sie am einfachs-ten unterhalb eines Verzeichnisses smarty an, das unterhalb des Ordners liegt,in dem die eigentlichen PHP-Seiten liegen. So finden Sie die relevanten Ver-zeichnisse schnell wieder.

Die Templates werden typischerweise in einem eigenen Verzeichnis namenstemplates abgelegt, um die Struktur des Servers möglichst transparent zu hal-ten. Beachten Sie, dass der Server Rechte zum Lesen und Ausführen für das Ver-zeichnis benötigt.

Ein weiterer Dateiordner, auf den der Server Lese- und Ausführungsrechtebenötigt, ist der Ordner config. In ihm können Sie später zentrale Konfigu-rationsdateien Ihrer Website ablegen.

In templates_c wird Smarty die kompilierten Templates ablegen. (Das c beitemplates_c steht für compiled.) Bei Smarty handelt es sich um eine kompi-

Professionelle Bibliotheken

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

lierende Template-Engine. Das heißt, dass die Templates, die ja in einer Smarty-eigenen Syntax geschrieben sind, nach PHP übersetzt werden. Der Vorteil dabeiist, dass Smarty, im Gegensatz zu anderen Template-Engines, nicht jedes Maldas ganze Template analysieren und interpretieren muss.

Das letzte Verzeichnis, cache, ist für eine der wohl interessantesten Funktionenvon Smarty nötig. Smarty ist in der Lage, eine einmal generierte Datei zucachen. Das heißt, aus dem Template und den dynamisch hinzugefügten Datenwird beim ersten Aufruf der Seite eine komplett fertige, statische HTML-Seitegeneriert. Wenn die besagte Seite also angefordert wird, muss nicht der PHP-Code ausgewertet werden; es kann einfach die statische Seite verschickt wer-den. Dazu aber später mehr.

In den Verzeichnissen templates_c und cache werden also Daten gespeichert.Daraus resultierend benötigt Smarty Schreibrechte für diese Verzeichnisse.Unter Windows müssen Sie sich keine weiteren Gedanken machen. Auch wennSie mit angemietetem Webspace arbeiten, haben Sie normalerweise kein Pro-blem. Bei den meisten Providern sind die Systeme so konfiguriert, dass der Ser-ver in die Verzeichnisse schreiben kann.

Nutzen Sie allerdings einen eigenen UNIX/Linux-Server, ist das unter Umstän-den nicht ganz so einfach. Zunächst müssen Sie herausfinden, unter welchemBenutzernamen der Webserver ausgeführt wird. Das geht am einfachsten, in-dem Sie in der Konfigurationsdatei des http-Servers nachschauen. Die Konfigu-rationsdatei wäre beim Apache-Webserver (der ja in den meisten Fällen genutztwird) die Datei httpd.conf. Sollten Sie nicht wissen, wo die Datei liegt, gebenSie einfach find / -name httpd.conf ein. Wenn Sie die Datei gefunden habenund in das entsprechende Unterverzeichnis gewechselt sind, können Sie mitmore httpd.conf | grep ^User den Benutzer herausfinden, unter dem derApache ausgeführt wird. Es sollte nur eine Zeile ausgegeben werden. Hinter derDirektive User finden Sie den gesuchten Benutzernamen. Typischerweise lautetder Benutzername wwwrun, nobody oder apache.

Nachdem Sie den Namen des Benutzers kennen, können Sie auch die beidenVerzeichnisse mit den entsprechenden Rechten versehen. Am einfachsten log-gen Sie sich als Benutzer root ein und wechseln in das Elternverzeichnis voncache und templates_c.

Dann geben Sie einfach Folgendes ein:

chown wwwrun cachechmod 700 cachechown wwwrun templates_cchmod 700 templates_c

Smarty 193

194

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

Danach gehören die Verzeichnisse dem Benutzer wwwrun (wobei Sie wwwrundurch den Benutzernamen ersetzen, der auf Ihrem System genutzt wird), under hat alle Rechte auf das Verzeichnis.

Die Installation haben Sie jetzt hinter sich und können loslegen.

Für die Beispiele gehe ich davon aus, dass die PHP-Seiten in folgendem Ver-zeichnis liegen:

/var/www/html/CMS

Die anderen, vorgenannten Verzeichnisse liegen alle unterhalb vonCMS/smarty/. Um mit Smarty arbeiten zu können, benötigen Sie die absolutenPfadangaben der Verzeichnisse. Wenn Sie sich nicht sicher sind, wie derabsolute Pfad auf Ihrem Server lautet, können Sie ihn einfach mit dem Befehl

<?phpecho $_SERVER['SCRIPT_FILENAME'];

?>

ausgeben lassen.

Um eine Seite auf Basis von Smarty zu erstellen, müssen Sie zuerst die KlasseSmarty.class.php, die sich im Unterverzeichnis libs befindet, einbinden. DesWeiteren benötigt Smarty die Information, wo die einzelnen Unterverzeich-nisse zu finden sind.

Der Kopf einer Smarty-basierenden PHP-Seite würde in unserem Beispiel alsofolgendermaßen aussehen:

<?php// Eine Konstante, um Tipparbeit zu sparendefine ('PFAD', '/var/www/html/CMS/smarty/');

// Einbinden der Klasserequire (PFAD.'/libs/Smarty.class.php');

// Objekt instanziieren$smarty = new Smarty;

// Definition der Unterverzeichnisse// Bitte den Slash am Ende nicht vergessen!$smarty->template_dir= PFAD.'templates/';$smarty->config_dir=PFAD.'configs/';

Professionelle Bibliotheken

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

$smarty->compile_dir= PFAD.'templates_c/';$smarty->cache_dir= PFAD.'cache/';

// Hier kommt jetzt weiterer PHP-Code…?>

Diesen Code auf jeder Seite einzubauen, wäre nicht nur umständlich, sondernauch unflexibel. Würden die Daten in ein anderes Verzeichnis kopiert, müsstejede einzelne Datei korrigiert werden. Man könnte diesen ganzen Kopf in eineinclude-Datei auslagern, aber deutlich eleganter ist es, die Klasse Smarty zuerweitern und eine eigene Klasse zu generieren.

<?php// Eine Konstante, um Tipparbeit zu sparendefine ('PFAD', '/var/www/html/CMS/smarty/');

// Einbinden der ursprünglichen Klasserequire (PFAD.'/libs/Smarty.class.php');

// Deklaration der neuen Klasseclass MySmarty extends Smarty {

// Der neue Konstruktorfunction MySmarty () {

// Konstruktor der Ursprungsklasse aufrufen$this->Smarty();

// Definition der Unterverzeichnisse// Bitte den Slash am Ende nicht vergessen!$this->template_dir= PFAD.'templates/';$this->config_dir= PFAD.'configs/';$this->compile_dir= PFAD.'templates_c/';$this->cache_dir= PFAD.'cache/';

}}

?>

Die Deklaration Ihrer eigenen, neuen Klasse können Sie einfach im Unterver-zeichnis smarty unterhalb von CMS als MySmarty.class.php speichern. Sie soll-ten sie nicht mit in das Verzeichnis libs legen, da das bei Updates schnell zuIrritationen führen kann.

Smarty 195

196

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

Nun können wir endlich anfangen, mit Smarty zu arbeiten. Das erste Beispielsoll zeigen, wie die Daten von der PHP-Seite an das Template übergeben wer-den. Hierzu kennt smarty die Methode assign. Mit Hilfe von

$smarty->assign('titel', 'Hallo Welt ;-)');

würden Sie der smarty-Variable titel den Wert Hallo Welt ;-) zuweisen.

Die komplette PHP-Seite sieht folgendermaßen aus:

<?phprequire 'smarty/MySmarty.class.php';//Instanziieren eines neuen Objekts$smarty = new MySmarty;//Initialisieren der Variablen$smarty->assign ('titel','Hallo Welt');$smarty->assign ('text','Unsere erste Seite');

$smarty->display("eins.tpl");?>

Die Methode display dient dazu, das Template, in diesem Fall eine Datei mitNamen eins.tpl, aufzurufen, ihm die Werte zu übergeben und es anzeigen zulassen.

Nun brauchen wir allerdings noch das Template, um die Daten formatieren undausgeben zu lassen. Das fertige Template speichern Sie dann bitte als eins.tplim Verzeichnis templates. Die smarty-Befehle innerhalb des Templates werdenstandardmäßig in geschweifte Klammern, also { und }, eingeschlossen. Um denInhalt einer Variablen ausgeben zu lassen, können Sie einfach den Variablen-namen, eingeleitet durch ein Dollarzeichen ($) in geschweiften Klammern,schreiben. So würde

{$EinWert}

den Inhalt der Variable $EinWert ausgeben. Das komplette Template eins.tplkönnte also folgendermaßen aussehen:

<html><head>

<title>{$titel}</title></head><body>

<b>{$text}</b></body>

</html>

Professionelle Bibliotheken

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

Sobald Sie jetzt die PHP-Seite im Browser aufrufen, wird das Template kom-piliert und ausgegeben. Sie werden feststellen, dass Smarty im Ordnertemplates_c ein neues Verzeichnis angelegt hat, in dem das kompilierte Tem-plate liegt.

Die Methode assign beherrscht nicht nur die Übergabe von einfachen String-Literalen, sondern auch von Variablen, Arrays und sogar Objekten. MöchtenSie im Template auf den Inhalt einer PHP-Variable zugreifen, so müssen Sieihren Inhalt auch erst einer Smarty-Variable zuweisen4. Mit

$smarty->assign('Vorname',$Vorname);

würden Sie den Inhalt der PHP-Variable $Vorname also an die Smarty-VariableVorname übergeben. Auch ein Array können Sie auf diesem Weg an Smartyübergeben:

<?phprequire 'smarty/MySmarty.class.php';$smarty = new MySmarty;

$arbeitstage = array ("Montag", "Dienstag","Mittwoch","Donnerstag","Freitag");

$smarty->assign('arbeitstage',$arbeitstage);

$erfinder = array("gluehbirne"=>"Thomas Alva Edison","auto"=>"Carl Friedrich Benz");

$smarty->assign('erfinder',$erfinder);

$smarty->display("zwei.tpl");?>

Die Ausgabe der einzelnen Werte aus den Arrays würde so realisiert werden:

<html><head>

<title>Erfinder</title></head><body>

Der erste Tag der Woche ist {$arbeitstage[0]} <br />Das Auto wurde von {$erfinder.auto} erfunden

</body></html>

4 Die Smarty-Dokumentation ist an dieser Stelle leider ein wenig missverständlich formu-liert. Es ist nicht möglich, direkt auf eine PHP-Variable zuzugreifen, ohne sie zu »assig-nen«.

Smarty 197

198

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

Die einzelnen Werte eines indizierten Arrays werden also über die bekanntePHP-Syntax5 angesprochen, wohingegen der Zugriff auf ein assoziatives Arraydadurch erfolgt, dass der jeweilige Schlüssel an den Namen des Arrays ange-hängt wird. Natürlich wird auch der Zugriff auf mehrdimensionale Arraysunterstützt. Würde es also z.B. folgendes Array geben

$ma=array(array("name"=>"Maier", "kontakt"=>

array("telefon"=>"123456789","mobil"=>"987654321")));

so könnten Sie – natürlich erst, nachdem Sie es an Smarty übergeben haben –den Namen mit {$ma[0].name} und die Telefonnummer mit {$ma[0].kon-takt.telefon} ausgeben lassen.

Der Zugriff auf die Eigenschaften von Objekten ist nicht schwieriger. Um dieEigenschaft name eines Objekts person auszugeben, nutzen Sie einfach die vonPHP bekannte Syntax, also {$person->name}.

Sie müssen allerdings nicht immer alles an Smarty übergeben. Mit Hilfe derreservierten Variable {$smarty} können Sie auf diverse vordefinierte Werteund Systemvariablen zugreifen. So enthält {$smarty.now} beispielsweise denaktuellen Timestamp (zum Formatieren steht der Modifikator date_format zurVerfügung).

{$smarty} ermöglicht Ihnen auch den Zugriff auf die vordefinierten, »super-globalen« Variablen von PHP. Das heißt, wenn Sie den Namen des Servers aus-lesen wollen, können Sie in PHP $_SERVER['SERVER_NAME'] nutzen. Innerhalbdes Templates können Sie auf {$smarty.server.SERVER_NAME} zugreifen. Ver-allgemeinert kann man sagen, dass der Name des superglobalen Arrays einfachin Kleinbuchstaben umgewandelt und an $smarty angehängt wird. Danachfolgt dann der Index des Wertes, auf den Sie zugreifen wollen. Möchten Sie alsoz.B. den Wert von $_SESSION['KundenNummer'] ansprechen, schreiben Sie ein-fach {$smarty.session.KundenNummer}. Die Philosophie, den Namen desArrays Eins zu Eins in Kleinbuchstaben umzuwandeln, wurde bei $_COOKIE lei-der nicht konsequent verfolgt. Möchten Sie auf den Wert eines Cookies zugrei-fen, so nutzen Sie bitte {$smarty.cookies.NameDesCookies}.

6.1.1 Modifikatoren

Nachdem Sie nun wissen, wie Sie Werte an das Template übergeben, stellt sichnatürlich die Frage, wie Smarty Sie bei der Ausgabe und Formatierung unter-

5 Anstelle von $arbeitstage[0] würde Smarty auch $arbeitstage.0 unterstützen. Dadiese Syntax aber nicht dokumentiert ist, sollten Sie sie sicherheitshalber nicht nutzen.

Professionelle Bibliotheken

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

stützen kann. Hierzu gibt es eine ganze Menge nützlicher Modifikatoren, mitdenen Sie das Erscheinungsbild der Seite steuern können.

Um die Ausgabe eines Wertes zu steuern, wird er mit einer | (Pipe genannt,engl. für Rohr, Röhre) an den Modifikator weitergeleitet. Um den Inhalt derVariable $name komplett in Großbuchstaben auszugeben, steht z.B. upper zurVerfügung.

Die Anweisung {$name|upper} übergibt den Inhalt von $name an den Modi-fikator upper, der den gesamten Text in Großbuchstaben umwandelt. BeachtenSie, dass vor und nach der Pipe kein Leerzeichen stehen darf. Natürlich könnenSie auch mehrere Modifikatoren zu einer Befehlsabfolge kombinieren. Jederweitere Modifikator wird einfach wieder mit einer Pipe an den Vorgänger ange-hängt. So würde

{$name|upper|spacify}

den übergebenen Text erst in Versalien konvertieren und danach gesperrt aus-geben. Aus einem Peter würde also ein P E T E R.

Das Verhalten einiger Modifikatoren können Sie auch dadurch beeinflussen,dass Sie ihnen Parameter übergeben. spacify fügt, wenn es ohne Parameteraufgerufen wird, normale Leerzeichen zwischen den Zeichen ein. Möchten Sienun aber sicherstellen, dass ein Wort nicht einfach »mittendrin« umbrochenwird, müssen Sie dafür sorgen, dass die Spaces durch die Entität &nbsp; ausge-tauscht werden. Um spacify mitzuteilen, welches das Trennzeichen sein soll,übergeben Sie es einfach nach einem Doppelpunkt:

{$name|spacify:"&nbsp"}

Wie Sie feststellen, ist Smarty sehr flexibel und nimmt Ihnen viel Arbeit ab.Natürlich kann man Funktionen wie upper und spacify auch jederzeit selbstprogrammieren, aber nicht jeder Kunde möchte Sie dafür bezahlen, dass Siejedes Mal das Rad neu erfinden. Und außerdem können Sie mit der gewonnenZeit vielleicht auch mal etwas anderes machen, als immer nur am Rechner zusitzen.

Leider ist es in diesem Rahmen nicht möglich, alle Modifikatoren und Funk-tionen von Smarty vorzustellen. Die wichtigsten sollen hier erläutert werden.Eine komplette Dokumentation (auch in Deutsch) finden Sie unter http://smarty.php.net/docs.php.

Smarty 199

200

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

Wichtige Modifikatoren im Überblick

capitalize

capitalize wandelt den ersten Buchstaben jedes übergebenen Wortes in einenGroßbuchstaben um; das ist teilweise praktisch, um englischsprachige Über-schriften auszugeben.

PHP-Datei$smarty=new MySmarty;$smarty->assign('ausgabe','hallo welt');$smarty->display('template.tpl');

template.tpl{$ausgabe|capitalize}

AusgabeHallo Welt

count_characters, count_words, count_sentences, count_paragraphs

Die count-Funktionen ermöglichen es Ihnen, Texte in jeder nur erdenklichenWeise durchzählen zu lassen. count_characters liefert die Anzahl der Buch-staben und Satzzeichen, count_words bestimmt die Anzahl der Wörter. DerModifikator count_sentences zählt die Anzahl der Sätze, wobei momenten lei-der nur Sätze erkannt werden, die mit einem normalen Punkt enden. count_paragraphs errechnet, wie viele Absätze enthalten sind. Ein Absatz wirdjeweils an einem abschließenden \n erkannt.

PHP-Datei$smarty=new MySmarty;$smarty->assign('ausgabe',"Eine Zeile.\nNoch eine Zeile!");$smarty->display('template.tpl');

template.tplZeichen: {$ausgabe|count_characters}<br />W&ouml;rter: {$ausgabe|count_words}<br />S&auml;tze: {$ausgabe|count_sentences}<br />Abs&auml;tze: {$ausgabe|count_paragraphs}<br />

AusgabeZeichen: 24Wörter: 5Sätze: 1Absätze: 2

Professionelle Bibliotheken

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

date_format

Mit date_format können Sie einen Timestamp, z.B. von {$smarty.now}, in einlesbares Datum konvertieren. Das Datumsformat können Sie mit Hilfe einesFormatstrings festlegen. Dieser String basiert auf den Platzhaltern, die von derPHP-Funktion strftime() genutzt werden. Da die komplette Liste der Platz-halter recht lang ist, finden Sie in Tabelle 6.1 nur die wichtigsten. (Die kom-plette Liste finden Sie unter www.php.net/strftime.)

Einige dieser Platzhalter hängen von den aktuellen Lokalisierungseinstellungenab. Mit der PHP-Funktion setlocale() können Sie die Lokalisierung ändernund somit z.B. steuern, ob die Namen der Tage auf Deutsch, Englisch oder ineiner anderen Sprache ausgegeben werden. Weitere Informationen hierzu fin-den Sie in Kapitel 9.

Platzhalter Bedeutung

%a Erste drei Buchstaben des Wochentags

%A Kompletter Name des Wochentags

%b Abgekürzter Monatsname

%B Kompletter Monatsname

%d Tag des Monats, zweistellig (01 bis 31)

%e Tag des Monats ohne führende Null (1 bis 31)

%m Nummer des Monats, zweistellig (01 bis 12)

%U Wochennummer

%y Jahr ohne Jahrhundert (also 03 für 2003)

%Y Komplette Jahreszahl

%H Stunden im 24-Stunden-Format (00 bis 24)

%I Stunden im 12-Stunden-Format (01 bis 12)

%M Minuten als Zahl (00 bis 59)

%R Zeit im 24-Stunden-Format ohne Sekunden

%S Sekunden als Zahl (00 bis 59)

%T Aktuelle Zeit, 24-Stunden-Format mit Sekunden

%x Datum im regional üblichen Format

%X Uhrzeit im regional üblichen Format

%c Übliche Datums- und Zeitdarstellung

Tabelle 6.1 Platzhalter für date_format

Smarty 201

202

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

PHP-Datei$smarty=new MySmarty;$smarty->display('template.tpl');

template.tpl{$smarty.now|date_format:"}

AusgabeHallo Welt

default

Sollten Sie auf eine Variable zugreifen, die leer oder nicht gesetzt ist, so erhaltenSie einen Leerstring als Ausgabe. Möchten Sie in einem der vorgenannten Fälleeinen Standardwert definieren, so können Sie das mit dem Modifikatordefault tun. default kennt einen optionalen Parameter, der als Standardwertder Variable definiert wird. Dieser wird ausgegeben, wenn die Variable leeroder nicht gesetzt ist.

PHP-Datei$smarty=new MySmarty;$smarty->assign('arbeitgeber','ACME Inc.');$smarty->display('template.tpl');

template.tplArbeitgeber: {$arbeitgeber|default:"Nicht genannt"}<br />Verdienst: {$verdienst|default:"Zu wenig"}

AusgabeArbeitgeber: ACME Inc.Verdienst: Zu wenig

escape

Dieser Modifikator ist einer der praktischsten überhaupt. Er kann den Inhalteiner Variable für verschiedene Zielformate maskieren. Das heißt, er kannIhnen dabei helfen, Texte, in denen Umlaute enthalten sind, z.B. in korrektesHTML mit Entitäten zu verwandeln.

Die Angabe des Zielformats erfolgt mit Hilfe eines Parameters. Sie dürfen eineder folgenden Konstanten zu diesem Zweck nutzen:

Parameter Bedeutung

html Konvertiert die Zeichen &" ' < > in Entitäten.

htmlall Wandelt alle HTML-Sonderzeichen in Entitäten um.

Tabelle 6.2 Formatangaben für escape

Professionelle Bibliotheken

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

Geben Sie keinen Parameter an, so wird html als Standardwert genutzt.

Die Parameter hex und hexentity sind dazu gedacht, E-Mail-Adressen zu ver-bergen. Es gibt eine ganze Anzahl von Programmen, so genannte Harvesteroder Spam Bots, die das Internet nach E-Mail-Adressen durchsuchen, um sie fürSpammer nutzbar zu machen. Eine Konvertierung mit hex bzw. hexentity bie-tet zumindest einen minimalen Schutz vor Harvestern. Mit hex sollten Sie E-Mail-Adressen ausgeben lassen, die für den Browser gedacht sind (also der Teilnach dem <a href="mailto:), und mit hexentity den Teil, der für die Darstel-lung zuständig ist.

PHP-Datei$smarty=new MySmarty;$smarty->assign('titel','Schöne süße Soße geköchelt');$smarty->assign('vote','Soße toll');$smarty->assign('email','[email protected]');$smarty->display('template.tpl');

template.tpl{$titel|escape:"htmlall"}<br /><a href="vote.php?v={$titel|escape:"url"}">Toll</a><br /><a href="mailto:{$email|escape:"hex"}"> {$email|escape:"hexentity"}</a>

AusgabeSch&ouml;ne s&uuml;&szlig;e So&szlig;e gek&ouml;chelt<br /><a href="vote.php?v=Sch%F6ne+s%FC%DFe+So%DFe+gek%F6chelt">

Toll</a><br /><a href="mailto:%61%40%73%6f%73%73%65%2e%64%65">&#x61;&#x40;&#x73;&#x6f;&#x73;&#x73;&#x65;&#x2e;&#x64;&#x65;</a>

url Konvertiert in einen korrekten URL.

quotes Maskiert Anführungszeichen mit einem Backslash.

hex Wandelt den Text in eine hexadezimale Darstellung um.

hexentity Konvertiert den Text in hexadezimale Entitäten.

Parameter Bedeutung

Tabelle 6.2 Formatangaben für escape (Forts.)

Smarty 203

204

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

nl2br

nl2br entspricht der gleichnamigen Funktion in PHP. Sie wandelt Zeilenumbrü-che, die über die Tastatur eingegeben wurden, bzw. \n in ein <br />-Tag um.Beachten Sie, dass Smarty sich hier, genau wie PHP, XHTML-konform verhältund ein <br /> anstatt eines <BR> ausgibt.

PHP-Datei$smarty=new MySmarty;$smarty->assign('text','Smarty macht\nPHP noch toller');$smarty->display('template.tpl');

template.tpl

{$text|nl2br}

AusgabeSmarty macht<br />PHP noch toller

regex_replace

Der Modifikator regex_replace gibt Ihnen die Möglichkeit, einen Text durcheinen anderen zu ersetzen. Er unterstützt, wie Sie sicher schon vermutet haben,reguläre Ausdrücke und bekommt zwei Parameter übergeben. Der erste Para-meter ist das Suchmuster, das ersetzt werden soll, und der zweite ist der Text,durch den ersetzt wird. Der reguläre Ausdruck ist in der »Perl-Compatible«-Syn-tax von PHP anzugeben. Weitere Informationen zur Syntax finden Sie unterhttp://www.php.net/pcre.

PHP-Datei$smarty=new MySmarty;$smarty->assign('text','Heute ist der 12.1.2003');$smarty->display('template.tpl');

template.tpl{$text|regex_replace:"/Heute ist/":"Gestern war"}

AusgabeGestern war der 12.1.2003

strip_tags

Möchten Sie alle HTML-Tags aus einem Text herausfiltern, können Sie strip_tags nutzen.

Professionelle Bibliotheken

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

PHP-Datei$smarty=new MySmarty;$smarty->assign('text','Donuts <b>sind lecker</b>');$smarty->display('template.tpl');

template.tpl

{$text|strip_tags}

AusgabeDonuts sind lecker

truncate

truncate ist ein ungemein praktischer Modifikator. Mit ihm sind Sie in derLage, einen Text bei der Ausgabe nach einer bestimmten Anzahl von Zeichen»abzuschneiden«.

truncate unterstützt drei optionale Parameter. Beim ersten handelt es sich umeine Zahl, die angibt, nach wie vielen Zeichen der Text abgeschnitten werdensoll. Geben Sie keinen Wert an, so wird die Ausgabe auf 80 begrenzt. Derzweite Parameter ist ein Text, der an die Ausgabe angehängt wird. Hier bietetsich z.B. ein »…« an. Mit dem letzten Wert, einem Boolean, legen Sie fest, obtruncate mitten in einem Wort trennen darf oder ob das letzte Wort immerkomplett ausgegeben werden soll. Mit false legen Sie fest, dass ein Wort nichtabgeschnitten werden darf. In diesem Fall würde vor dem Wort getrennt.

PHP-Datei$smarty=new MySmarty;$smarty->assign('text','Heute ist es sehr regnerisch.');$smarty->display('template.tpl');

template.tpl{$text|truncate:15:"...":false}

AusgabeHeute ist es...

wordwrap

Auch wordwrap stellt einen sehr praktischen Modifikator dar. Er versetzt Sie indie Lage, die Laufweite eines Textes festzulegen. Das heißt, Sie könnenangeben, nach wie vielen Zeichen ein Zeilenumbruch erfolgen soll.

Der Modifikator akzeptiert drei optionale Parameter. Der erste definiert dieLaufweite in Zeichen. Mit dem zweiten können Sie festlegen, welche Zeichen-kette zum Umbrechen genutzt wird. Zuletzt können Sie bestimmen, ob mitten

Smarty 205

206

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

im Wort umbrochen werden darf (true) oder ob das Wort immer komplett indie nächste Zeile übernommen werden soll (false). Sollte ein Wort vor-kommen, das länger als die vorgegebene Laufweite ist, so wird es bei Angabevon false nicht umbrochen, sondern in kompletter Länge ausgegeben.

PHP-Datei$smarty=new MySmarty;$smarty->assign('text','Heute ist es sehr regnerisch.');$smarty->display('template.tpl');

template.tpl{$text|truncate:15:"<br />\n":false}

AusgabeHeute ist es<br />sehr<br />regnerisch.

6.1.2 Funktionen

Neben den schon besprochenen Modifikatoren gibt es in Smarty auch eineganze Menge von Funktionen. Der Unterschied zwischen Funktionen undModifikatoren besteht darin, dass Modifikatoren die Formatierung eines Varia-bleninhalts beeinflussen. Eine Funktion hingegen bezieht sich nicht direkt aufden Inhalt einer Variablen oder hat einen eigenen Rückgabewert. Des Weiterensind hier auch Kontrollstrukturen wie Schleifen und if-Abfragen enthalten.

Sie werden feststellen, dass die Syntax von Funktionen nicht ganz so einfach istwie die von Modifikatoren, dafür sind sie aber deutlich leistungsfähiger.

Möchten Sie z.B. JavaScript-Code in ein Template einbinden, könnte das durch-aus zu Problemen führen. Anweisungsblöcke werden in JavaScript in ge-schweifte Klammern eingeschlossen. Da Smarty diese aber auch verwendet,kann es durchaus passieren, dass die Smarty-Engine Ihren Code falsch interpre-tiert. Um dieses zu verhindern, können Sie den »fremden Code« mit der Funk-tion {literal}{/literal} ausblenden. Das heißt, der nachfolgende Code-block würde vor der Smarty-Engine verborgen.

{literal}<script language="javascript"}

if (""==self.document.eingabeform.name.value){

Professionelle Bibliotheken

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

window.alert("Bitte Namen eingeben");}

</script>{/literal}

An diesem kleinen Beispiel können Sie schon erkennen, dass Funktionen inSmarty sich deutlich von denen in PHP unterscheiden.

Einige der wichtigsten Funktionen habe ich nachfolgend für Sie zusammenge-stellt. Eine komplette Liste finden Sie unter http://smarty.php.net/docs.php.

if, else, elseif

Die if-Funktion ermöglicht Ihnen eine Fallunterscheidung. Sie bietet dieselbenMöglichkeiten wie in PHP, kennt jedoch noch ein paar zusätzliche Features.

Operator Synonym(e) Bedeutung

== eq Test auf exakte Gleichheit(eq = equal)

!= ne, neq Test auf Ungleichheit(ne = not equal)

< lt Kleiner als(lt = lower than)

> gt Größer als(gt = greater than)

<= lte Kleiner gleich(lte = less than or equal)

>= gte Größer gleich(gte = Greater than or equal)

is even is not odd Testet, ob eine Zahl gerade ist.

is odd is not even Testet, ob eine Zahl ungerade ist.

is div by Testet, ob eine Zahl glatt durch eine andere teilbar ist.

is even by Gruppiert Zahlen in Blöcke und testet ob die Zahl in einem Block mit gerader Ordnungszahl liegt.

is even by 2 liefert für 0 und 1 ein true, für 2 und 3 ein false und für 4 und 5 wieder ein true …

is odd by Gruppiert Zahlen in Blöcke und testet, ob die Zahl in einem Block mit ungerader Ordnungszahl liegt.

Tabelle 6.3 Operatoren und ihre Bedeutung

Smarty 207

208

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

Beachten Sie, dass zwischen den Variablen bzw. Konstanten und dem Ver-gleichsoperator ein Leerzeichen stehen muss. Des Weiteren werden natürlichdie Booleschen Operatoren || (Synonym: or) und && (Synonym: and) unter-stützt. Wie in PHP ist auch hier die Bindung des && stärker als die des ||. Beikomplexeren Ausdrücken sollten Sie also Klammern nutzen, um Fehler zu ver-meiden.

PHP-Datei$smarty=new MySmarty;$smarty->assign('geschlecht','m');$smarty->assign('name','Meier');$smarty->display('template.tpl');

template.tplSehr{if $geschlecht eq "m" or $geschlecht eq "M"}

geehrter Herr{else}

geehrte Frau{/if}{$name}

AusgabeSehr geehrter Herr Meier

section, sectionelse

Um Sie bei der Ausgabe von Arrays zu unterstützen, sieht Smarty zwei Schlei-fenkonstrukte vor. Das ist zum einen die {section}{/section}-Funktion, diefür indizierte Arrays gedacht ist, und zum anderen die {foreach}{/foreach}-Funktion für assoziative Arrays. Leider reicht dieser Rahmen nicht aus, um auch{foreach} zu besprechen. Die Funktionsweise ist der Section aber sehr ähnlich,so dass ein kurzer Blick in die Dokumentation sicher ausreichend ist.

{section} bekommt mindestens zwei Parameter übergeben. Der erste Para-meter (name) ist der Name der Section und der zweite (loop) das Array, dasabgearbeitet werden soll.

PHP-Datei$smarty=new MySmarty;$smarty->assign('namen',array("Maier","Gergens","Sauser"));$smarty->display('template.tpl');

Professionelle Bibliotheken

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

template.tpl{section name=SectNamen loop=$namen}

{$namen[SectNamen]}<br />{/section}

AusgabeMaier<br />Gergens<br />Sauser<br />

Mit den optionalen Parametern step und max können Sie die Schrittweite bzw.die maximale Zahl der Iterationen festlegen. Eine Section, die mit

{section name=SectNamen loop=$namen step=2 max=3}

eingeleitet wird, gibt also jedes zweite Element aus, wobei maximal drei Schlei-fendurchläufe ausgeführt werden. Mit anderen Worten: Es würden die Ele-mente null, zwei und vier ausgegeben. Geben Sie für step eine negative Zahlan, so läuft die Schleife rückwärts. Um eine Section zu definieren, die nichtbeim ersten Element anfängt, können Sie mit dem Parameter start einenIndexwert angeben, von dem an begonnen wird.

Innerhalb einer Section stellt Smarty Ihnen einige Eigenschaften zur Verfügung,die die Arbeit deutlich erleichtern. Die Variable iteration enthält beispiels-weise die Nummer des aktuellen Schleifendurchlaufs. Um in der SectionSectNamen ihren Wert ausgeben zu lassen, müssten Sie auf

{$smarty.sections.SectNamen.iteration}

zugreifen. Es wird also immer $smarty.sections und der Name der Sectionvor den Bezeichner geschrieben.

Hier eine Übersicht der wichtigsten Section-Eigenschaften:

Eigenschaft Inhalt

index Index des Feldes, das gerade abgearbeitet wird, beginnend mit 0.

iteration Nummer des Schleifendurchlaufs, beginnend mit 1.

first Liefert ein true, wenn es der erste Schleifendurchlauf ist.

last Liefert ein true, wenn es der letzte Schleifendurchlauf ist

total Gesamtzahl der Schleifendurchläufe; kann auch nach der Section abge-fragt werden.

Tabelle 6.4 Wichtige Eigenschaften für section

Smarty 209

210

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

PHP-Datei$smarty=new MySmarty;$smarty->assign('namen',array("Maier","Gergens","Sauser"));$smarty->display('template.tpl');

template.tpl{section name=SectNamen loop=$namen}

{if $smarty.section.SectNamen.first}<table border="1">

{/if}<tr>

<td>{$smarty.section.SectNamen.index}</td><td>{$smarty.section.SectNamen.iteration}</td><td>{$namen[SectNamen]}</td>

</tr>{if $smarty.section.SectNamen.last}

</table>{/if}

{/section}{$smarty.section.SectNamen.total} Namen ausgegeben

Ausgabe<table border="1">

<tr><td>0</td><td>1</td><td>Maier</td>

</tr><tr>

<td>1</td><td>2</td><td>Gergens</td>

</tr><tr>

<td>2</td><td>3</td><td>Sauser</td>

</tr></table>3 Namen ausgegeben

Professionelle Bibliotheken

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

Sections können aber nicht nur einfache Arrays abarbeiten. Sie können mitihnen auch jederzeit indizierte Arrays, die assoziative Arrays beinhalten, aus-geben. Dies ist beispielsweise sehr praktisch, wenn Sie Daten aus einer Daten-bank ausgelesen haben und in ein entsprechend »großes« Array überführen. Sowürde {$namen[SectNamen].Vorname} auf das Array $namen zugreifen unddarin auf den Inhalt des Array-Elements Vorname.

Ein wirklich praktisches Feature ist {sectionelse}. Es kann immer mal pas-sieren, dass man ein leeres Array übergibt. Für diesen Fall können Sie einen Teildefinieren, der dann ausgegeben wird. Das heißt, die Section

{section name=SectNamen loop=$namen}{$namen[SectNamen]}<br />

{sectionelse}Leider konnten keine Namen gefunden werden.

{/section}

gibt entweder den Inhalt des Arrays aus oder – wenn das Array leer ist – denText: Leider konnten keine Namen gefunden werden.

Mit Hilfe einer Section können Sie auch, was leider nicht in der Dokumentationerwähnt ist, eine for-Schleife simulieren. Mit

{section name=SectFor loop=5}

würden Sie beispielsweise eine Schleife erstellen, die fünfmal durchlaufenwird.

include

Eine der ärgerlichsten Sachen bei der Erstellung von HTML-Seiten ist, dass beiden meisten Seiten eine ganze Menge Code identisch ist. Neben den üblichenDingen wie dem Head, Meta-Tags o.Ä. sind auch die Navigation oder die Lay-out-Tabellen identisch.

Die Funktion {include} dient dazu, ein externes Template in das aktuelle Tem-plate einzubinden. Mit

{include file="header.tpl"}

wird die Datei header.tpl eingebunden.

PHP-Datei$smarty=new MySmarty;$smarty->assign('name','Claudia');$smarty->display('template.tpl');

Smarty 211

212

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

template.tpl{include file="header.tpl"}

{$name}</body>

</html>

header.tpl<html>

<head><title></title>

</head><body>

Ausgabe<html><head>

<title></title></head><body>

Claudia</body>

</html>

debug

Bei der Programmierung wird es nie ganz zu verhindern sein, dass »unerklär-liche Phänomene« dazu führen, dass der Code sich nicht wie erwartet verhält.Das kann natürlich auch bei Smarty passieren, aber Smarty kann zumindest beider Fehlersuche behilflich sein. Der Befehl {debug} öffnet ein Fenster, in demalle aktuell zugewiesenen Variablen ausgegeben werden.

Abbildung 6.2 Smartys Debug-Konsole

Professionelle Bibliotheken

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

Neben den hier genannten Funktionen gibt es noch eine recht stattliche Anzahlvon anderen Funktionen. Hierunter sind Funktionen, die automatisch HTML-Tags oder Tabellen generieren können und Sie in die Lage versetzen, Berech-nungen durchführen zu lassen. Natürlich können Sie Smarty auch noch umeigene Funktionen erweitern. Stöbern Sie einfach mal in der Online-Dokumen-tation – es lohnt sich.

6.1.3 Caching

Eine der Funktionalitäten, die Smarty so interessant machen, ist die Möglich-keit, Dateien zu cachen. Das heißt, Smarty kann eine statische Kopie einer Seiteerstellen, die einmal aufgerufen wurde. Bei einem nachfolgenden Aufruf kannder Server dann diese Kopie der Seite ausliefern und muss den PHP- bzw.Smarty-Code in einer Seite nicht erneut auswerten. Diese Vorgehensweise spartviel Systemperformance. Vielleicht werden Sie sich jetzt die Frage stellen, obhier nicht der Teufel mit dem Beelzebub ausgetrieben wird. Sicher hat es Vor-teile, Systemressourcen zu sparen, aber damit sind die Seiten doch nicht mehrtopaktuell, sondern haben einen veralteten Content. In den meisten Fällen istes aber so, dass Content sich nicht sekündlich ändert und teilweise sogar überTage, Monate oder Jahre hinweg unverändert bleibt. Stellen Sie sich z.B. einNews-System einer Firma vor, in dem die neuesten Unternehmensnachrichtenveröffentlicht werden. Nachdem eine Nachricht einmal publiziert wurde, wirdsie sich mit größter Wahrscheinlichkeit nicht mehr ändern. Aber auch, wennSie eine Site erstellen, deren Inhalte sich häufiger ändern, kann die Caching-Funktionalität sehr hilfreich sein. Sie können nämlich ohne Probleme steuern,wie lange eine statische Kopie einer Seite gültig sein soll und in welchen Zeit-abständen sie zu aktualisieren ist.

Rein technisch gesehen, wird die statische Kopie der Seite im Unterverzeichniscache angelegt. Die Datei liegt nicht direkt in dem Verzeichnis. Unterhalb voncache werden noch weitere Verzeichnisse angelegt, die dann die Dateien ent-halten. Der Name der Kopie setzt sich aus dem Namen des Templates und derEndung .php zusammen.

Um eine Seite zu cachen, weisen Sie der Eigenschaft caching einfach den Werttrue zu. Die Seite verbleibt dann eine Stunde im Cache, bevor sie neu generiertwird. Sie können natürlich auch selbst definieren, wie lange eine Datei imCache verbleiben soll. Hierzu können Sie der Eigenschaft cache_lifetime eineGültigkeitsdauer in Sekunden zuweisen.

require_once 'smarty/MySmarty.class.php';$smarty = new MySmarty;$smarty->caching=true; //Caching einschalten

Smarty 213

214

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

$smarty->cache_lifetime=600; //Speicherzeit 600 Sekunden// Hier könnte Code für Datenbankzugriffe etc. stehen$smarty->display('index.tpl');

Beim Aufruf dieser Seite wird also eine statische Kopie erstellt. Leider überprüfterst die Methode display(), ob die Datei bereits im Cache liegt. Der gesamteCode (wie Datenbankzugriffe etc.) würde also ausgeführt, nur um dann festzu-stellen, dass die Datei bereits gecacht ist. Das ist natürlich nicht optimal. Umdas zu vermeiden, können Sie den gesamten Code vor dem Aufruf der Methodedisplay() in eine if-Abfrage »verpacken«. Die Methode is_cached() kann füreinzelne Templates überprüfen, ob eine vorhandene Kopie noch gültig ist oderob sie aktualisiert werden muss. Sie liefert einen booleschen Wert und kannsomit direkt als Bedingung eingesetzt werden.

// Code zum Einbinden von Smarty etc.if (!$smarty->is_cached('index.tpl')){

//Code für Datenbankzugriff o.Ä.}$smarty->display('index.tpl');

Bei der Nutzung von is_cached() müssen Sie beachten, dass die Methode eintrue liefert, wenn die Datei im Cache liegt. Das heißt, Sie müssen den Rück-gabewert mit Hilfe des Negationsoperators (!) umkehren.

6.2 PEAR

PEAR ist eine weitere sehr professionelle Bibliothek, die Sie bei der Arbeit mitPHP unterstützt. Bei genauer Betrachtung ist die Bezeichnung »Bibliothek«schon fast eine Beleidigung für PEAR. Das »PHP Extension and ApplicationRepository« stellt eine umfangreiche Erweiterung für PHP dar und beinhalteteine große Anzahl von Vereinfachungen und Verbesserungen für die Arbeit mitPHP. Aufgrund der großen Menge von verfügbaren Paketen kann ich hier leidernur einige exemplarisch erläutern.

6.2.1 Installation

Zum Ersten stellt sich natürlich die Frage, wie Sie an PEAR kommen. Kein Pro-blem, Sie haben es schon – zumindest haben Sie es mit größter Wahrscheinlich-keit. Mit Erscheinen von PHP 4.3 wurde PEAR offizieller Bestandteil von PHP.Da ich davon ausgehe, dass Sie eine Version >4.3 haben, werde ich die Instal-lation bei älteren Versionen nicht erläutern6.

6 Eine Erläuterung zur Installation von PEAR unter älteren PHP-Versionen finden Sie unterhttp://pear.php.net/manual/de/installation.php.

Professionelle Bibliotheken

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

{ // Ja => Adresse auslesen und Mail senden$mail=$_GET["adr"];// Adresse wieder brauchbar machen$mail=str_replace("|","@",$mail);echo "<script type=\"text/javascript\">";echo "self.location.href='mailto:$mail';";echo "self.close();";echo "</script>";

}// Mail-Adresse, die genutzt werden soll$mail="[email protected]";// Konvertierung fuer die Bildschirmausgabe$ausg=str_replace("@","_at_",$mail);// Konvertierung fuer den "Link"$link=str_replace("@","|",$mail);// Ausgabe des Linksecho "<a target=\"_blank\"

href=\"$_SERVER[PHP_SELF]?adr=$link\">$ausg</a>";

Der JavaScript-Code generiert eine Weiterleitung auf die E-Mail-Adresse. Daauch hier das Pseudo-Protokoll mailto: genutzt wurde, öffnet sich der E-Mail-Client. In der nächsten Zeile wird mit self.close() das zweite Fenster wiedergeschlossen. Auch wenn diese Variante ein zweites Fenster öffnet, empfinde ichsie als eleganter. Allerdings muss einschränkend erwähnt werden, dass dieFunktionalität natürlich nur dann gewährleistet ist, wenn der Client auch Java-Script akzeptiert.

9.7 Shared Memory

Es kann vorkommen, dass Sie mit mehreren voneinander unabhängigen Pro-zessen arbeiten, die Daten miteinander austauschen müssen. Ein typisches Bei-spiel ist ein Chat. Die Chat-Applikation, die für die Ein- und Ausgabe der Datenzuständig ist, wird von mehreren Benutzern gleichzeitig ausgeführt. Jeder derProzesse muss Daten mit allen anderen austauschen, damit User B auch lesenkann, was User A geschrieben hat. Natürlich können die Prozesse alle auf einegemeinsame Datenquelle wie eine Datenbank oder eine Datei zugreifen, aberdas ist sehr ressourcenintensiv.

Auf UNIX-kompatiblen Systemen steht für eine solche Interprozess-Kommuni-kation (IPC) Shared-Memory zur Verfügung. Hierbei handelt es sich um einenSpeicherbereich, der von Prozessen direkt angesprochen werden kann undnicht an die Laufzeit eines Scripts gebunden ist. Auf ein solches Speicherseg-

Shared Memory 491

492

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

ment können mehrere Prozesse unabhängig voneinander zugreifen, so dass eseine ideale Möglichkeit ist, um kleinere Datenmengen auszutauschen.

Hierbei handelt es sich um eine Betriebssystemfunktion, die mit UNIX System-V eingeführt wurde. Somit können Sie diese Funktionalität auch nutzen, umDaten mit Anwendungen auszutauschen, die in anderen Programmiersprachenerstellt wurden.

Um mit Shared-Memory zu arbeiten, stehen Ihnen drei Pakete von Funktionenzur Verfügung. Zum Ersten ist das die Gruppe der shm_*-Funktionen. Sie stehennur dann zur Verfügung, wenn Ihr PHP mit --enable-sysvshm konfiguriertwurde. Diese Funktionen dienen dazu, einen Speicherbereich beim Systemanzumelden und dort Daten mit Hilfe von Variablen abzulegen. Die zweiteGruppe von Funktionen beginnt mit dem Präfix sem_. Sie dienen dazu, Sema-phoren13 zu verwalten. Semaphoren werden dazu genutzt, den Zugriff auf denSpeicher zu verwalten. Da mehrere Prozesse mit demselben Speicherbereicharbeiten, müssen Sie verhindern, dass zwei Prozesse gleichzeitig schreiben.Auch wenn ein Prozess liest, während ein anderer schreibt, könnte das dazuführen, dass beschädigte Daten ausgelesen werden. Semaphoren stehen nurdann zur Verfügung, wenn PHP mit der Option --enable-sysvsem konfigu-riert wurde.

Die Funktionen des dritten Komplexes beginnen alle mit dem Präfix shmop_und ist nur dann verfügbar, wenn PHP mit --enable-shmop konfiguriertwurde. Sie geben Ihnen die Möglichkeit, Daten mit Nicht-PHP-Prozessen aus-zutauschen. Sie kennen keine Möglichkeit, Daten in Form von Variablen abzu-legen, sondern können direkt auf Speicheradressen zugreifen. Da dieses Buchsich aber nicht mit Systemprogrammierung auseinander setzt, werden dieseFunktionen hier nicht besprochen14.

Der Zugriff auf Shared Memory ist leider nicht ganz so komfortabel wie die nor-male Arbeit mit PHP. Zuerst müssen Sie beim System mit shm_attach() einenSpeicherbereich anbinden. Die Funktion bekommt einen ganzzahligen Wert alsSchlüssel übergeben, anhand dessen der Speicherbereich eindeutig zu identi-fizieren ist. Jeder andere Prozess, der auf diesen Speicherbereich zugreifen soll,muss das Speichersegment über denselben Schlüssel anbinden. Beim erstenZugriff auf ein Speichersegment wird dieses neu angelegt. Als zweiten, optio-nalen Parameter können Sie der Funktion die gewünschte Größe den Speicher-

13 Definition laut Duden: Se|ma|phor, das od. (österr. nur:) der; -s, -e <gr.-nlat.; »Zeichen-träger«>: Mast mit verstellbarem Flügelsignal zur optischen Zeichengebung (z.B. zumAnzeigen von Windstärke u. -richtung an der Küste)

14 Sollten Sie Informationen zu diesen Funktionen benötigen, finden Sie diese im PHP-Online-Manual unter www.php.net/shmop. Eine deutsche Übersetzung ist derzeit nochnicht verfügbar.

Praxis-Lösungen für den Programmieralltag

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

bereichs in Byte mit übergeben. Definieren Sie diese nicht, wird die Default-Einstellung aus der php.ini übernommen, die durch sysvshm.init_mem vorge-geben ist. Ist dieser Eintrag nicht vorhanden, wird eine Größe von 100 000 Bytegenutzt. Konnte der Speicher reserviert werden, liefert die Funktion eine IDzurück, über die das Speichersegment angesprochen werden kann. Im Fehler-fall wird eine Warnung ausgegeben, und false zurückgegeben.

@$mem_id=shm_attach(1,100000);if (false==$mem_id){

die ("Konnte Speicher nicht reservieren: $php_errormsg");}

Zum Ablegen und Auslesen von Variablen stehen Ihnen die Funktionen shm_put_var() und shm_get_var() zur Verfügung. Variablen werden in diesem Fallallerdings nicht über Namen, sondern über Nummern angesprochen. Der ersteParameter ist in beiden Fällen die ID des Speicherbereichs. Nach der ID folgtdie Nummer der Variable. Im Fall von shm_put_var() folgt als letzter Parameterder Wert, der in der Variable abgelegt werden soll.

shm_put_var($mem_id,1,"Hallo Welt"); //Speichert den Wert$wert=shm_get_var($mem_id,1); // Liest Variable 1 wieder ausecho $wert; // Gibt Hallo Welt aus.

Endet Ihr Script, sollten Sie das Speichersegment mit shm_detach() wiederabtrennen. Der Speicher bleibt aber weiterhin reserviert, und die Inhalte blei-ben erhalten. Erst wenn Sie shm_remove() aufrufen, steht der Speicher demSystem wieder zur Verfügung. Vergessen Sie nicht, beim Beenden des letztenProzesses diese Funktion aufzurufen, da sonst unnötig Speicher blockiert wird.

Um zu verhindern, dass mehrere Prozesse gleichzeitig auf den Speicher zugrei-fen, werden die Semaphoren-Funktionen genutzt. Auch ein solches »Signal«muss zuerst erstellt werden. Dazu ist die Funktion sem_get() vorgesehen, dieeinen eindeutigen Schlüssel (einen Integer-Wert) übergeben bekommt. Sieerstellt einen neuen Semaphor und liefert seine ID zurück. Sollte schon einermit diesem Schlüssel existieren, liefert sie seine ID zurück. Mit dieser ID kön-nen Sie die Funktion sem_acquire() aufrufen. Sie bekommt die ID als Para-meter übergeben und reserviert den Semaphor so lange, bis Sie ihn mit sem_release() wieder freigeben. Kann der Semaphor nicht für Sie reserviert wer-den, weil ein anderer Prozess darauf zugreift, wartet die Funktion, bis er wiederfrei wird. Nur wenn ein Fehler auftritt, gibt sie false zurück. Auch hier gilt,dass ein nicht mehr benötigter Semaphor vom letzten Prozess mit sem_remove() entfernt werden sollte.

Shared Memory 493

494

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

// ID des Semaphors auslesen@$sem_id=sem_get(1);if (false==$sem_id){

die ("Konnte Semaphor-ID nicht auslesen: $php_errormsg");}// Semaphor reservierenif (false==sem_acquire($sem_id)){

die ("Konnte Semaphor nicht reservieren: $php_errormsg");}

// Hier kann ungestoert mit dem// Shared Memory gearbeitet werden

if (false==sem_release($sem_id)){

die ("Konnte Semaphor nicht freigeben: $php_errormsg");}// Semaphor entfernen (nur wenn er nicht mehr gebraucht wird)if (false==sem_remove($sem_id)){

die ("Konnte Semaphor nicht entfernen: $php_errormsg");}

Listing 9.49 Reservieren eines Semaphors

Vielleicht wundern Sie sich, dass in diesem Beispiel jede produktive Anweisungmit einer Fehlerabfrage versehen ist. Das liegt daran, dass ein Fehler imUmgang mit Shared Memory und Semaphoren recht weit reichende Konse-quenzen haben kann, da sie, wenn sie z.B. nicht gelöscht werden, System-ressourcen blockieren.

So viel zu der Theorie der Funktionen. Am Beispiel eines kleinen Messengersmöchte ich Ihnen die Möglichkeiten und Probleme von Shared Memory zeigen.Bei dem Messenger handelt es sich um eine »Minimal-Anwendung«. Er dientzur direkten Kommunikation zwischen zwei Personen und verfügt weder übereine Benutzerverwaltung noch über ein Login.

Das Fenster besteht aus zwei Frames. Im oberen Bereich werden die Nachrich-ten dargestellt und im unteren eingegeben. Somit sind es vier Prozesse, die mit-einander kommunizieren müssen. Hierbei ist zum einen zu gewährleisten, dassnur vollständige Daten von den Lese-Prozessen empfangen werden. Zum ande-

Praxis-Lösungen für den Programmieralltag

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

ren dürfen Daten, die noch nicht von beiden Chat-Teilnehmern gelesen wordensind, nicht überschrieben werden. Für einen »echten« Chat könnte man an die-ser Stelle eine Queue implementieren. Da es hier aber nur um eine Beispiel-anwendung für Shared Memory gehen soll, habe ich darauf verzichtet.

Abbildung 9.36 Der Messenger

Alle Dateien greifen auf die Include-Datei conn.php zu, die das gemeinsameSpeichersegment anbindet bzw. anlegt und den Semaphor bereitstellt. DesWeiteren werden hier einige Konstanten definiert.

<?phpdefine ("SEM_NR",4711); //Nummer des Semaphorsdefine ("SHM_NR",815); // Nummer des Speichersegmentsdefine ("READERS",1); // Variablennummerdefine ("MSG_ID",2); // Variablennummerdefine ("MESSAGE",3); // Variablennummer

// Zeit-Limit auf unendlich, damit das Script nicht abbrichtset_time_limit(0);// Shared Memory kreieren bzw. anbinden$mem_id=shm_attach(SHM_NR,100000);if (false==$mem_id){

die ("Konnte Speicher nicht reservieren: $php_errormsg");}// Semaphor kreieren oder Handle auslesen

Shared Memory 495

496

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

$sem_id=sem_get(SEM_NR);if (false==$sem_id){

die ("Konnte Semaphor-ID nicht auslesen: $php_errormsg");}?>

Listing 9.50 Include-Datei zur Definition von Konstanten

Die Anwendung nutzt drei Variablen, auf die mit Hilfe von Konstanten zuge-griffen wird. Variable 3 – die Konstante MESSAGE – beinhaltet die eigentlicheNachricht. In der Variable 2 wird eine ID für jede Message abgelegt. Da derLese-Prozess eine Nachricht nicht mehrfach darstellen soll, muss er prüfen kön-nen, ob er die Nachricht, die sich im Speicher befindet, bereits ausgelesen hat.Dies wird mit Hilfe der hier abgelegten, eindeutigen ID realisiert. In der erstenVariable, die mit der Konstante READERS angesprochen wird, wird protokolliert,wie viele User die Nachricht bereits ausgelesen haben. Hiermit wird sicherge-stellt, dass alle User die Information aus MESSAGE ausgelesen haben, bevor sieüberschrieben wird.

Die Datei send.php, die im unteren Frame dargestellt wird, übernimmt meh-rere Aufgaben. Zum einen dient sie zum Darstellen des Formulars und zumSpeichern der Nachricht im Shared-Memory. Die andere Aufgabe besteht darin,einen Shutdown für alle Prozesse zu initiieren, wenn der Chat beendet wird.Der Code des Hauptprogramms in dieser Datei lautet:

require_once("conn.php"); //Einbinden der Resourcenif (true==isset($_POST["logout"])) // Logout gefordert?{ // Funktion aufrufen und Programm beenden

logout($mem_id,$sem_id);exit;

}

form_ausgeben(); // Eingabe-Formular ausgeben

if (true==isset($_POST["sagen"])) // Soll etwas gesagt werden?{

send_message($mem_id,$sem_id);}

Listing 9.51 Script zum Senden der Eingaben

Das Programm kann zwischen drei Zuständen unterscheiden. Bekommt Siekeine Werte übergeben, gibt sie ein Formular aus. Andernfalls verschickt sie

Praxis-Lösungen für den Programmieralltag

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

eine Nachricht oder beendet die Kommunikation. Die Funktion zur Ausgabedes Formulars gibt ein Text-Feld mit zwei Submit-Buttons aus.

function form_ausgeben(){

echo "<form method=\"POST\">";echo "<input name=\"write\" />";echo "<input type=\"submit\" value=\"sagen\"

name=\"sagen\" />";echo "<input type=\"submit\" value=\"Log Out\"

name=\"logout\" />";echo "</form>";

}

Listing 9.52 Funktion zur Ausgabe des Eingabe-Formulars

Anhand der Namen der Buttons wird im Hauptprogramm unterschieden, obder Benutzer eine Nachricht verschicken oder sich ausloggen möchte. DieFunktion zum Verschicken der Daten bekommt die IDs des Speichersegmentsund des Semaphors übergeben.

function send_message($mem_id, $sem_id){

// Zufallszahlengenerator initialisierenmt_srand((double)microtime()*1000000);

// Zufallszahl als Message-ID auslesen$msg_id = mt_rand();// Semaphor reservierenif (false==sem_acquire($sem_id)){

die ("Semaphor nicht reservierbar: $php_errormsg");}// Auslesen, wie viele User noch nicht gelesen haben@$anzahl_gelesen=shm_get_var($mem_id,READERS);// Haben schon alle gelesen?while (false != $anzahl_gelesen &&

0 < $anzahl_gelesen){

// Nein, Semaphor wieder freigebenif (false==sem_release($sem_id)){

die ("Semaphor nicht freizugeben: $php_errormsg");

Shared Memory 497

498

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

}// kurz warten, damit andere Prozesse den// Semaphor reservieren koennenusleep(20);// Semaphor erneut reservierenif (false==sem_acquire($sem_id)){

die ("Semaphor nicht reservierbar: $php_errormsg");}// Wie viele haben die Nachricht inzwischen gelesen?$anzahl_gelesen=shm_get_var($mem_id,READERS);

}// Neue Nachricht speichernshm_put_var($mem_id,MESSAGE,$_POST["write"]);// Anzahl der Leser wieder auf zwei setzen.// Zwei haben also noch nicht gelesenshm_put_var($mem_id,READERS,2);// ID der Nachricht speichernshm_put_var($mem_id,MSG_ID,$msg_id);

// Semaphor wieder freigebenif (false==sem_release($sem_id)){

die ("Konnte Semaphor nicht freigeben: $php_errormsg");}

}

Listing 9.53 Funktion zum Senden der Eingaben

Beim Speichern der Nachricht ist zu gewährleisten, dass die Nachricht nur danngespeichert wird, wenn alle Benutzer die vorhergehende ausgelesen haben.Hierzu wird in der Variable, die über die Konstante READERS angesprochenwird, die Zahl 2 abgelegt. Die Anzahl der User ist somit fix auf zwei festgelegt.Eine Anwendung für mehr Nutzer müsste an dieser Stelle auf Informationenaus der Benutzerverwaltung zurückgreifen. Bei jeder Leseoperation subtra-hieren die jeweiligen Leseprozesse jeweils 1, so dass hier, nachdem alle Pro-zesse gelesen haben, eine Null enthalten ist. Haben noch nicht alle Prozessegelesen, wartet der Schreibprozess mit Hilfe einer Schleife, in der der Semaphorfreigegeben und später wieder reserviert wird. Würde er nicht freigegeben,könnten die Leseprozesse ihn nicht reservieren.

Praxis-Lösungen für den Programmieralltag

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

Die Nachrichten-ID, die vom Leseprozess genutzt wird, um festzustellen, ob ereine bestimmte Nachricht schon ausgegeben hat, basiert auf einer Zufallszahl.

Die Funktion logout() bekommt auch die IDs von Semaphor und Speicherseg-ment übergeben und entfernt diese dann aus dem Speicher.

function logout($mem_id,$sem_id){

@sem_remove($sem_id);@shm_remove($mem_id);echo "Die Kommunikation wurde beendet!";

}

Listing 9.54 Logout-Funktion

Das ist natürlich kein Logout, wie man es sich im üblichen Sinn vorstellt. Mel-det sich einer der Partner bei einer Eins zu Eins-Kommunikation ab, ist dieKommunikation nicht weiter möglich. Die anderen Prozesse müssen also mit-geteilt bekommen, dass die Anwendung beendet wird. Das könnte z.B. übereine weitere Variable realisiert werden. Allerdings müsste dann der letzte Pro-zess der Anwendung »wissen«, dass er der letzte ist, und dann Speicher undSemaphor wieder freigeben. Der Aufwand wäre also deutlich höher. Daher gibtdieser Prozess die Ressourcen wieder frei. Die anderen Prozesse stellen dannfest, dass sie diese nicht mehr reservieren können, und beenden sich. DieseFunktion wird natürlich nur dann ausgeführt, wenn einer der User den Button»Log Out« betätigt. Schließen beide Ihre Fenster, verbleiben Speichersegmentund Semaphor im Speicher des Servers. Das könnte nur dadurch unterbundenwerden, dass mit Hilfe des JavaScript-Eventhandlers onUnload eine weiterePHP-Datei aufgerufen wird. Alternativ zum Event-Handler können Sie aucheine Logout-Funktion im Lese-Prozess nutzen. Hier müsste sie zusätzlich zu dennachfolgend beschriebenen Funktionen implementiert werden und würde fol-gendermaßen lauten:

function logout($mem_id,$sem_id){

@sem_remove($sem_id);@shm_remove($mem_id);

}

Binden Sie diese Funktion mit register_shutdown_function() ein, ist auchsichergestellt, dass keine »Leichen« im Speicher verbleiben, wenn die User dieFenster schließen, ohne sich auszuloggen.

Shared Memory 499

500

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

Der Lese-Prozess besteht primär aus einer Endlosschleife, die versucht eineneue Nachricht aus dem Shared Memory auszulesen.

<?phpfunction logout(){ // gibt JavaScript-Code für ein Forward auf

// eine andere Seite ausecho "<script type=\"text/javascript\">";echo "parent.location.href=\"out.html\";";echo "</script>";

}

require_once("conn.php");// Speichert die ID der zuletzt gelesenen Nachricht// Wird zum Initialisieren mit -1 belegt$id_last_read=-1;

// Ein Zaehler zum Zaehlen der Schleifendurchlaeufe$count=0;

// Endlosschleife zum Auslesen der Datenwhile (true){

// Versuch, den Semaphor zu reservieren. Liefert// die Funktion false, wurde der Semaphor von einem// anderen Prozess entfernt -> logoutif (@false==sem_acquire($sem_id)){

logout();exit;

}

// Auslesen der Message-ID@$msg_id=shm_get_var($mem_id,MSG_ID);// Wurde diese Nachricht schon gelesen und ausgegeben?// Vergleich mit $id_last_readif (false!=$msg_id &&

$id_last_read!=$msg_id){

// Anzahl der Leser auslesen$readers=shm_get_var($mem_id,READERS);

Praxis-Lösungen für den Programmieralltag

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

$readers=$readers-1; // Um eins reduzieren// Und wieder speichernshm_put_var($mem_id,READERS,$readers);// ID der aktuellen Nachricht speichern$id_last_read=$msg_id;// Message auslesen und ausgeben lassen$message=shm_get_var($mem_id,MESSAGE);echo "<br />$message";

}else{ // Die aktuelle Nachricht wurde schon ausgegeben.

// Bei jedem zehnten Schleifendurchlauf ein Leerzeichen// ausgeben, damit der Browser kein Timeout produziertif (0==$count%10){

echo " ";}// Schleifenzaehler um eins erhöhen$count+=1;

}// Semaphor freigebenif (false==sem_release($sem_id)){

die ("Konnte Semaphor nicht freigeben: $php_errormsg");}flush(); // Daten an den Browser schickenusleep(500);//Schlafen, damit andere Prozesse laufen koennen

}?>

Listing 9.55 Lese-Prozess des Messengers

Die Endlosschleife versucht zuerst, den Semaphor zu reservieren. Liefert dieFunktion ein false zurück, existiert er nicht mehr, und die Funktion logout()wird aufgerufen. Sie gibt eine Zeile JavaScript an den Browser aus, der auf dieDatei out.html verweist. Sie generiert eine Meldung wie »Die Kommunikationwurde beendet«.

Konnte der Semaphor reserviert werden, wird zuerst die ID der Nachricht aus-gelesen. Entspricht die neu ausgelesene ID nicht der zuvor ausgelesenen, wirddie Nachricht ausgelesen und an den Browser geschickt. Wurde die Nachrichtallerdings schon ausgegeben, wird bei jedem zehnten Schleifendurchlauf ein

Shared Memory 501

502

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

Leerzeichen an den Browser geschickt, damit dieser die Kommunikation nichtabbricht.

Nachfolgend wird der Semaphor wieder freigegeben, und der Prozess schläftfür 500 Mikrosekunden. Durch diese Pausenlänge ist gewährleistet, dass andereProzesse ein ausreichendes Zeitfenster vorfinden und der Client nicht auf Nach-richten warten muss.

Abbildung 9.37 Der Messenger in Aktion

Dieser Messenger ist keine perfekte Anwendung, da er nur als Beispiel dienensoll. Nichtsdestotrotz denke ich, dass die wesentlichen Punkte deutlich werden.

Bei der Entwicklung solcher Anwendungen wird es Ihnen sicher mal passieren,dass ein Speichersegment oder ein Semaphor im Speicher »vergessen« wird. Ineinem solchen Fall sind die UNIX-Befehle ipcs und ipcrm hilfreich. ipcs stehtfür inter-process communication status und generiert eine Übersicht allermomentan im System angemeldeten IPC-Ressourcen. Die Ausgabe von ipcskönnte so aussehen:

Praxis-Lösungen für den Programmieralltag

1

2

3

4

5

6

7

8

9

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

Abbildung 9.38 Typische Ausgabe von ipcs

Im oberen Bereich der Ausgabe finden Sie die Speichersegmente, gefolgt vonden Semaphoren und den System-V-Message Queues, die hier nicht erwähntwurden. Daran, dass der Besitzer wwwrun ist, können Sie erkennen, dass eineRessource vom Webserver und somit von PHP generiert wurde. Des Weiterenkönnen Sie anhand der Spalte key die von Ihnen generierten Daten erkennen.Die bei der Erstellung von Ihnen vergebenen Nummern finden sich hier wie-der. Das Speichersegment wurde mit der Nummer 815 generiert. Die 815 ent-spricht einem hexadezimalen 32f, das hier als Schlüssel zu finden ist. Gleichesgilt für den Semaphor, der den dezimalen Schlüssel 4711 hat, was einer hexa-dezimalen 1267 entspricht.

Ist nach Ende des letzten Prozesses eine »Leiche« im Speicher verblieben, kön-nen Sie diese mit ipcrm (inter-process communication remove) entfernen. WennSie den Befehl mit dem Parameter -m und der internen ID eines Speicherseg-ments aufrufen, wird dieses entfernt. Die jeweilige ID finden Sie in der zweitenSpalte. In diesem Beispiel entfernt ipcrm -m 9601028 das Speichersegmentvom Benutzer wwwrun. Einen Semaphor können Sie mit dem Parameter -s undseiner ID entfernen.

9.8 Installationsprogramme

Wenn Sie heutzutage eine PHP-Anwendung aus dem Internet herunterladen, istes in vielen Fällen leider so, dass Sie eine lange Anleitung bekommen, wie dieSoftware einzurichten ist. Sie müssen Verzeichnisse, Datenbanken und Tabellenanlegen oder in diversen Konfigurationsdateien Pfade und Benutzernamen

Installationsprogramme 503

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

Index

$_REQUEST 457$this 110.htaccess 149:: 114� 106@ 150@author 317@copyright 317@deprecated 317@example 318@filesource 318@global 318@ignore 319@link 319@name 318@package 319@param 320@return 320@see 321@since 321@static 322@staticvar 322@subpackage 319@todo 322@uses 321@var 322@version 317\\ 33\r 33\t 33__ 536__autoload 136__call 133__clone 128__construct 131__destruct 131__get 135__set 135__toString 136404 Fehler 1797-Bit-ASCII 4058-Bit-ASCII 405

AAbkürzungen 70Ablaufgeschwindigkeit 542

abstract 138Abstrakte Klassen 138Access-Keys 345ActionScript 355addChild (PEAR) 261addFormat (PEAR) 254addRequire (PEAR) 245addroot (PEAR) 261addUser (PEAR) 247addWorksheet (PEAR) 251Aktionen 356alnum 384alpha 384Alternative PHP-Syntax 57Altersüberprüfung 481Anforderungsprofil (Pflichtenheft) 270Anker in regulären Ausdrücken 386Annahmen überprüfen 274ANSI-Zeichensatz 405apd 548Arbeitsblatt 250Arbeitsmappe 250arithmetisches Mittel 96array_diff 327array_intersect 327array_map 42array_merge 327array_pop 330array_push 329, 330array_reduce 40, 42array_search 43array_shift 329array_unique 327array_walk 40Arrays 37

assoziative 37indizierte 37Löcher in 38sortieren 44Suche in 43

arsort 45ASCII 405ascii, POSIX-Klasse 384ASCII-Code 33ASCII-Code in regulären Ausdrücken

382

Index 607

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

ASCII-Dateien 400asiatische Sprachen 408asort 45ass_call 276Assembler 542assert 273ASSERT_ACTIVE 275ASSERT_BAIL 276ASSERT_CALLBACK 275, 276assert_options 275ASSERT_QUIET_EVAL 275ASSERT_WARNING 275assertEquals 288Assertion 276assertNotNull 288assertNull 289assertTrue 289assign_(Smarty) 196Ausgangsvoraussetzung (Pflich-

tenheft) 270Auskommentieren 58Auth (PEAR) 236Authentifizierung (PEAR) 235AuthName 241AuthType_ 241AuthUserFile 241auto_profile_mode 555Autocommit 590autoload 136

BBackreferences 388Backslash 33Base64 428base64_decode 528base64_encode 528Basic (AuthType) 242Basisklasse 105Bäume 331BBCode 460bcadd 578Bcc 424bccomp 579bcdiv 579BCMath 578bcmod 579bcmul 579bcpow 579

bcpowmod 579bcsqrt 579bcsub 579Bedingte Ausdrücke 391Bedingungen 75

komplexe 68Type-Casting 77

Benchmark 548Benutzer-DSN 597Betriebsonzept 270Bibliotheken

Abhängigkeiten 101Bedingte Funktionen 102Dateiendung 95Datenbankverbindung 97externe 93Fehlerbehandlung 100Funktionen 96Funktionsdesign 99Nebeneffekte von Fuinktionen 101Rückgabewerte von Funktionen 100Tippfehler 98Variablenfunktionen 103Veraltete Funktionen 101Vorgabewerte für Parameter 99Wiederaufrufbarkeit 100Wrapper-Funktionen 101

Bildrate 357blank, POSIX-Klasse 384Boolean 27BOOLEAN MODE 602Boundary 429break 83Browser-Interlink Debugging 295Bühne 356

CCache

Cache_Function 572Cache_Output 574call 572end 575Garbage Collection 576get 570isCached 570isExpired 570remove 572

Cache_Function 572

608 Index

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

cache_lifetime_(Smarty) 214Cache-Systeme 568Caching (Smarty) 213cal_days_in_month 352call 133Callback-Funktion bei assert 275Call-Stack 291capitalize 200Carriage Return 401case-sensitive 87Casting

explizites 35catch 174Cc 424cd 400CHAR 586checkdate 352chunk_split 430class_exists 95, 120CLF 181Client URL 517clone 128close (PEAR) 252CMS 190cntrl, POSIX-Klasse 384Code-Hints 18Coder 273Code-Review 272Comma Separated Values 409Commit 590Common Logfile Format 181Common Logfile Format � s. CLFconnect (PEAR) 223construct 131Content-Management-System 190Content-Management-System � s.

CMScontinue 83Controller 273Copy-on-Write 544Copyright 317count_characters 200count_paragraphs 200count_sentences 200count_words 200crack_opendict 476CrackLib 475CREATE TABLE 520

createSequence (PEAR) 229Cross Site Scripting 458Cross Site Scripting � s. XSSCross-Site Request Forgeries 461Cross-Site Request Forgeries � s. CSRFCSRF 461CSV-Dateien 409CSV-Dateien � s. Comma Separated

ValuescURL 517curl_exec 517curl_init 517curl_setopt 517

DData Source Name 597Data Source Name (PEAR) 223Data Source Name � s. DSN (PEAR)date 524date_format (Smarty) 201Datei-DSN 597Dateien 399Dateien von unterschiedlichen

Betriebssystemen 400Dateilocks 413Dateirechte 399Datenbank-Abfragen, Performance

560Datenbanken 580Datenformate, Datenbanken 586Datentypen 27Datenübergabe von PHP an Flash 371Datumsformat 527, 537daylight 524DB (PEAR) 222DB_FETCHMODE_ASSOC (PEAR) 231DB_FETCHMODE_FLIPPED (PEAR)

233DB_FETCHMODE_OBJECT (PEAR)

231DB_FETCHMODE_ORDERED (PEAR)

231DB_Result (PEAR) 230de.comp.lang.php 16Debgging mit PHPUnit 285debug 401debug (Smarty) 212debug_backtrace 273, 278

Index 609

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

debug_print_backtrace 273, 278Debug-Features 273Debugger, professionelle 289Debugging 273Debugging, lokales 289Debug-Routinen, eigene 280Debug-Sessions 290decimal_point 540default_handler 155Deklaration von Klassen 107Dekrement 82DELAYED, MySQL 595Delimiter, PCRE 381delRequire (PEAR) 245delUser (PEAR) 247Denormalisierung 561destruct 131Destruktor 108Digest (AuthType) 242digit, POSIX-Klasse 384DIN 66001 309DIN 66230 302DIN 66231 302DIN 66232 302Directory 399disconnect 227disk_free_space 509Diskussionsforum 338display 196display_errors 149dividiere() 168DocBlock 314DocBlock, Editor 22Dokumentation 301

Abhängigkeiten 304Anforderungen 302Aufgabenstellung 302Ausgangsvoraussetzung 302Globale Datenstrukturen 305Globale Variablen 304Klassen 304Konstanten 304Maßeinheiten 303Namenskonventionen 303Schnittstellen 303Style-Guide 303Top-Down-Strategie 303Versionierung 303

Versionsnummer 304Verzeichniskonventionen 303Zugriffsmodifikatoren 305Zweck der Datei 304

double Ticks 31DROP TABLE 521dropSequence_(PEAR) 229DSN 597DSN (PEAR) 223

EE_ERROR 147E_NOTICE 147E_USER_ERROR 147E_USER_NOTICE 147E_USER_WARNING 147E_WARNING 147Editor

Code analysieren 24Fehler 23Lesezeichen 23PHPEdit 17Quanta Plus 17SubEthaEdit 17

eh 163Eigenschaften 105, 107Eingabetext 357Einrückungen 66ELF 181Emacs 402E-Mail-Adressen, Schutz von 487Embedded-PHP 52Empfangsbestätigung 425empty 86Enclosure 411Entwicklungsserver 295Envelope 419, 424ERROR 146Error 404 179error_log 149error_reporting 147Error-Handler 146Error-Handling 145

eigene Error-Handler 152in Bibliotheken 165in Klassenbibliotheken 169in PHP 5 174

610 Index

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

Kundenfreundliche Fehlermeldung 158Logfile 159Negativ-Beispiel 145send_mail 163SMS 163

Error-Handling � s. Fehler-Behandlung

Error-Tracking 151escape (Smarty) 202escapeshellarg 471Excel 250, 411Exception werfen 175Exception-Handling in PHP 5 174exp 520Extended Logfile Format � s. ELFExtended Logile Format 181extends 118externe Bibliotheken 93extract 457eXtreme Programming 273

FFactory-Klasse 116

Fehlerbehandlung 117Fakultät 332Fallstricke 61Fallunterscheidungen 79false 27fclose 62Fehler-Behandlung 145Fehler-Dokumente 179Fehlerkontroll-Operator 150Fehlermanagement 157fetchInto (PEAR) 230fetchRow (PEAR) 230fgetcsv 409fieldset 344File_HtAccess (PEAR) 241File_Passwd (PEAR) 241final 141Finale Klassen 141fla 360Flash 355

_blank 364_parent 365_root 364_self 364

_top 365Aktionen 356Bildrate 357Bühne 356Caching verhindern 378CheckBox 357, 361ComboBox 362Datenübernahme 371dynamischer Text 357Eigenschafts-Fenster 357Eingabetext 357getSelectedIndex 366, 370getSelectedItem 366getURL 364getValue 365gotoAndPlay 376gotoAndStop 376ListBox 362ListBoxen 357loadVariables 371LoadVars 378Math-Objekt 379PushButton 363RadioButton 361random 379Schriftart 358Scrollbalken 359setEnabled 377setValue 377statischer Text 357Umlaute 368urlencode 372UTF-8 368Veröffentlichen 360XML 378Zeitleiste 356, 363

Flash UI Components 359Fließkommazahlen 28Float 27, 28flock 414, 565foreach 39, 82Formatierung 63Formulare

ActionScript 355clientseitige Prüfung 351Default-Werte 345Feldbreite 346Flash MX 355

Index 611

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

Gliederung 346isset 347Leserichtung 347Plausibilätskontrolle 351Postleitzahlen prüfen 353Select-Box 345Submit-Button 347Validitätsprüfung 351Value-Konvertierung 348Variable Feld-Anzahl 349Wertübergabe mit Arrays 350Wertübernahme 347

Formulare, Aufbau 343frac_digits 540freshmeat.net 189ftp-Server, im Editor einrichten 19ftruncate 416function_exists 95, 508Funktionen

undokumentierte 89Funktionsaufrufe

verschachtelte 66Funktionsnamen 73fwrite 264

GGenau rechnen 577Genauigkeit von Fließkommazahlen 28generateID 570Generation 504get 135get (PEAR) 264get_class 123get_class_methods 121get_class_vars 121get_declared_classes 121get_object_vars 125get_parent_class 125getAll (PEAR) 233getAssoc 233getAssoc (PEAR) 233getAuth (PEAR) 240getCode 176getCode (PEAR) 222getcwd 509getFile 176getLine 176getListOf (PEAR) 234

getMessage 177getMessage (PEAR) 222getRequire (PEAR) 245getSelectedIndex 366getSelectedIndices 370getSelectedItem 366gettext 534getURL_ 364getUserInfo (PEAR) 222getValue 365Gier 391globale Variablen 63gmdate 524GMP-Funktionen 580GMT 522gmtime 524GnuPG 439gotoAndPlay 376gotoAndStop 376Grafiken in Installationsprogrammen

527graph, POSIX-Klasse 384greedy 391Greenwich Mean Time 522Groß-/Kleinschreibung 87

HHarvester 487Header 419header 412heredoc 32hexadezimale Zahlen 28HexEdit 402Hinting 137hotscripts.com 189htaccess 96, 241

display_errors 149error_log 149error_reporting 149log_errors 149

htmlentities 407htmlspecialchars 408htpasswd 242, 246http-Statuscode 184

Ii18n 534if (Smarty) 207

612 Index

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

imagecolorallocate 489imagecreate 489imagettfbbox 489imagettftext 489implements_ 140in_array 43, 327include 63include (Smarty) 211include_once 93Info-ZIP 437ini_set 150Inkrement 82InnoDB 590Input-Felder 347Installation von Komponenten 515Installationsprogramme 503Installationsvoraussetzungen 504instanceof 138instanziiert 106Integer 27

Überlauf 35INTEGER, Datenbanken 586Interaktion mit Benutzern 343Interceptor-Methoden 133Interfaces 138Internationalisierung 534inter-process communication remove

503inter-process communication status

502Interprozess-Kommunikation 491Introspektion 120IPC 491ipcrm 502ipcs 502is_a 123is_cached (Smarty) 214is_readable 510is_subclass_of 125is_writable 510ISBN-Nummern 355isCached 570isError 170isError (PEAR) 222isExpired 570ISO 3166 538ISO 639-1 538isset 347

JJava 174JavaScript in PHP 67

Kkey_exists 44Klammerung 64Klasse 105Klassen untersuchen 120Klassennamen 73klonen von Objekten 128Knoten 331Kommentare 57

mehrzeilige 58Komodo 289Komponenten, Installation von 515Konfigurationsdateien 512Konstruktor 108Kontonummern 353Kontrollstrukturen 75Kreditkartennummern 355krsort 45ksort 45

Ll10n 534Laufbedingung 77LC_ALL 537legend 344Leistungsbeschreibung 304length 370Lesebestätigung 425Lesezeichen 23libcurl 517Lieferumfang (Pflichtenheft) 270LiFo 330limitQuery (PEAR) 232Line Feed 401linksassoziativ 75literal (Smarty) 206loadVariables 371LoadVars 378localeconv 540LOCK_EX 414LOCK_UN 414Locking-Mechanismus 416Locks 413log_errors 149

Index 613

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

logische Fehler 273logout (PEAR) 240Lokales Debugging 289Lokalisierung 534Lookahead 388Lookaround 388Lookbehind 388lower, POSIX-Klasse 384ls 400

MMacromedia 355Magic Numbers 60Magic Quotes 588magic_quotes_gpc 466, 588magic_quotes_runtime 588magische Funktionen 133mail 419Mails 419

Absender 423Base64 428base64_encode 430Bcc 424Boundary 429Cc 424chunk_split 430Content-Transfer-Encoding 427Dateianhang 429eingebundene Grafiken 434Empfänger 421Empfangsbestätigung 425Envelope 419, 424Errors-To 424first-class 426GnuPG 439Header 419HTML 428komprimieren 437Kopien 424Lesebestätigung 425MIME 426PGP 439Precedence 426Priorität 426proc_open 443Return-Receipt-To 425RFC 2822 420

RFC-1342 427str_replace 428text/plain 427Troubleshooting 423Umlaute 427Umlaute in Betreffzeile 427urlencode 428verschlüsseln 439X-Priority 426Zeichensatz 420Zeilenumbrüche 421

mailto 490Maschinen-Code 542md5 238Mehrsprachige Texte 534Member-Funktionen 105Member-Methoden 74Member-Variablen 105Mengen 327

Array 327Mengengerüst (Pflichtenheft) 270MenschMitTelefon 312Messenger 494method_exists 124Methoden 105, 108

private 74MIME 426Mitwirkungspflicht des Kunden (Pflich-

tenheft) 270modUser (PEAR) 248mon_decimal_point 540mon_thousands_sep 540money_format 538Multi-Byte-String 408myError 170MyISAM 590mysql_free_result 62mysql_get_server_info 507mysqldump 520mysqli 590mysqli_autocommit 590mysqli_commit 591mysqli_query 591mysqli_rollback 591mysqli_select_db 591MySQL-ODBC 597MySQL-Version 507

614 Index

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

NNachrichten-ID 499Namen

für Funktionen 73für Klassen 73für Konstanten 70für Variablen 70

Namensgebung 69Nassi-Shneidermann-Diagramme 307Neue Passwörter 473new 106Newsgroup 16nextID (PEAR) 229nl2br 404nl2br (Smarty) 204Notepad 16NOTICE 146NSD 307NTP 524number_format 538numCols (PEAR) 235numRows (PEAR) 235

Oob_get_contents 164Objekte 105

Case-Sensitivity 107deklaration von Eigenschaften 107Deklaration von Klassen 107Kopie 106Schnittstellen 110

Objektorientierte Programmierung 104deklarierte Klassen auslesen 121Erweiterte Techniken 114in PHP 5 126Introspektion 120PHP-interne Klassen 121Untersuchung von Objekten 123

ODBC 596odbc_commit 601odbc_connect 599odbc_error 600odbc_errormsg 600odbc_exec 599odbc_fetch_row 600odbc_result 600odbc_rollback 601

oktale Zahlen 28OOP 104Open Database Connectivity 596Operatoren

Casting-Operatoren 35ternärer 80Typ des Rückgabewerts 34Verknüpfungsoperator 32

Optionen für PCREs 392Ordnung 62Output_Cache 573Overhead 105

PPair Programming 273PAP 305Parameter 88parent 119parse_ini_file 513passiver Modus, ftp 20Passphrasen 474Passwörter 473Passwörter, generieren von 477Passwörter, speichern 480PCRE 380PEAR 214

addChild 261addFormat 254addroot 261addUser 247addWorksheet 251Auth, Paket 236Authentifizierung 235CLI 215close 252close, Paket Passwd 247connect 223createSequence 229DB_FETCHMODE_FLIPPED 233DB_Result 230delRequire 245delUser 247disconnect 227dropSequence 229DSN 223Fehlerbehandlung 221fetchInto 230fetchRow 230

Index 615

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

File_HtAccess 241File_Passwd 241get, Paket XML_Tree 264getAll 233getAssoc 233getAuth 240getCode 222getListOf 234getMessage 222getRequire 245getUserInfo 222htaccess 241ini_set 220Installation 214isError 222limitQuery 232logout 240modUser 248nextID 229numCols 235numRows 235Pfade 220Pfade Windows 220query, Paket DB 228require_once 221Sequence 228setAlign 255setBgColor 258setBold 254setColor 257setCustomColor 257setFetchMode 230setFgColor 258setItalic 256setNumFormat 258setPattern 258setProperties 244setRequire 244setSize 256setTextRotation 256setUnderline 254, 256Shared Server 217Spreadsheet_ Excel_Writer 250Storage Driver, Paket Auth 238Verbindungsaufbau, Paket DB 223verifyPassword 248Web-Installer 216write 251

writeBlank 253writeFormula 253writeNumber 252writeString 253writeUrl 253XML_Tree 260

Peer-Review 272Performance vs. Lesbarkeit 55Performance-Bremsen 547Performance-Tuning 542Perl Compatible Regular Expressions

380Pflichtenheft 269pg_dump 520PGP 439PGPKeys 441PHP

neue Versionen 89PHP 5

call 133Destruktoren 131Interceptor-Methoden 133Konstruktoren 131nicht deklarierte Eigenschaften 135nicht deklarierte Methoden 133statische Eigenschaften 130

php.inidisplay_errors 149error_log 149error_reporting 147log_errors 149

php_version 505phpDocumentor 310

CHM 323globalen Variablen 318HTML-Darstellung 323Packages 319PDF 323Subpackages 319Tag 317

PHPEdit 17PHP-Land-Caches 568PHPMyAdmin 592PHPUnit 285PHPUnit_TestCase 285Plausibilätskontrolle 351Port 37 525POSIX-Standard 384

616 Index

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

PostIdent 481Postinkrement 542precision (php.ini) 30preg_grep 397preg_match 381, 394preg_match_all 395preg_replace 396preg_replace_callback 397preg_split 398Preinkrement 543Primzahlen, Berechnung von 545print, POSIX-Klasse 384private 129Private Key 439proc_open 443Produktivserver 295Professionelle Debugger 289Profiling 555Programmablaufpläne 305Programmierstil 51Projekte, Dokumentation von 301Projektverwaltung, Editor 20protected 129Prototyp 105Prototypen 270Prüfsummenalgorithmen 353Prüfziffer 353public 129Public Key 439punct, POSIX-Klasse 384

QQualifier 72Qualitätsmerkmale 270Qualitätssicherung 269Quanta Plus 17Quantifier, PCRE 385Quelltext-Formatierung 63query (PEAR) 228Query-Caching 563Queues 329

RRace Condition 565raiseError 170RC1 505Referenzen 126RegEx 380

regex_replace (Smarty) 204register_globals 452register_shutdown_function 499Reguläre Ausdrücke 380Reihenfolge von Datenbankeinträgen

585Rekursion 331Release Candidate 505Release-Level, MySQL 507Remote Debugging 295Require 241require 63require_once 93restore_error_handler 155Return-Receipt-To 425Reviews 272RFC-1305 524RFC-1342 427RFC-2030 524RFC-2045 430RFC-2445 524RFC-2822 419RFC-868 524root 364Rot-Grün-Schwäche 343rsort 45RTFM 16Rücksprungadresse 294Rückwärtsreferenz 388

SSchleifen 81

typische Einsatzbereiche 83Schlüsselwörter in PHP 5 129Scrollpane 361section (Smarty) 208sem_acquire 493sem_get 493sem_release 493sem_remove 493Semaphor 492Sequence (PEAR) 228

löschen 229Serverzeit 522session_destroy 450session_set_cookie_params 450session_start 449set 135

Index 617

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

set_error_handler 152setAlign (PEAR) 255setBgColor (PEAR) 258setBold (PEAR) 254, 256setColor (PEAR) 257setCustomColor (PEAR) 257setFetchMode (PEAR) 230setFgColor (PEAR) 258setItalic (PEAR) 256setlocale 537setNumFormat_(PEAR) 258setPattern (PEAR) 258setRequire (PEAR) 244setSize (PEAR) 256setTextRotation (PEAR) 256setUnderline (PEAR) 254, 256setUp 285Shared Memory 491Shared-Server 89shed 402Shell-Injections 468shm_attach 492shm_detach 493shm_get_var 493shm_put_var 493shm_remove 493ShopCart 106show tables 533Sicherheit 446

Altersüberprüfung 481BBCode 460Bugfixes 448CrackLib 475Cross Site Scripting 458Cross-Site Request Forgeries 461E-Mail-Adressen 487escapeshellarg 471Fertige Lösungen 447Geltungsbereiche 456Generieren von Passwörtern 477Globals 452Harvester 487htmlentities 460Neue Passwörter 473Passphrasen 474Passwörter 473register_globals 452Session-ID 449

Sessions 448Shell-Injections 468Social-Engineering 473Speichern von Passwörtern 480SQL-Injection 464strip_tags 460unset 454Variable Funktionen 472Variablen initialisieren 454Vulnerability 446Zugriffsrechte 468

Simonyi, Charles 72Simpletext 16skalare Datentypen 27sleep 415Smarty 190

Arrays nutzen 197assign 196cache_lifetime 214Caching 213capitalize 200count_characters 200count_paragraphs 200count_sentences 200count_words 200date_format 201debug 212display 196Einbinden 194escape 202Funktionen 206if 207include 211Installation 191is_cached 214literal 206Modifikatoren 198, 199nl2br 204regex_replace 204section 208spacify 199strip_tags 204superglobale Variablen 198truncate 205upper 199wordwrap 205

SNTP 524Social-Engineering-Angriffe 473

618 Index

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

Softwareumgebung 504Sommerzeit 523sort 44space, POSIX-Klasse 385spacify 199späte Bindung 281Speicherplatz, verfügbarer 509Speichersegment 492Spreadsheet_ Excel_Writer (PEAR) 250SQL in PHP 67SQL-Injection 464Stacks 330Stapel 330static 130statische Deklaration 130statische Seiten 556stdClass 107Step Into 292Step Out 292Step Over 292strftime 538String 27, 31

maximale Länge 31Zugriff auf einzelne Zeichen 33

strip_tags (Smarty) 204stripslashes 589Struktogramme 305SubEthaEdit 17Subklasse 105Submit-Button 347Submuster 387sum 587Superklasse 105swf 360System-DSN 597sysvshm.init_mem 493

TTabellenstruktur in phpMyAdmin 593tabindex 345Tabulatorsprung 33Team-Review 272tearDown 285Template-Engine 190Templates 190Ternärer Operator 80testDiv 287Testing 137

testMul 287Test-Suite 286Textareas 347thousands_sep 540throw 175Ticks 31Time Protocol 524TIMESTAMP, MySQL 587ToDo 61Token 557toString 136touch 247Tracing 555track_errors 151Transaktionsorientierung 589TRICKY 62trigger_error 157true 27truncate (Smarty) 205try 174Turck MMCache 569Type Casting 27

automatisches 34Type Hinting 137Type Testing 137Typ-Konvertierung 34

Uuasort 45uksort 45UltraEdit 402Underscore 74Undokumentierte Funktionen 89Ungarische Notation 72Uninstall 531Uninstall-Informationen 531Unit 273UNIX System V 492UNIX-Datei-System 399unset 62Untersuchung von Objekten 123UPDATE 587upper 199upper, POSIX-Klasse 385urlencode 372Userland-Caches 568usleep 418usort 45

Index 619

www.galileocomputing.de - Besser PHP programmieren - Leseprobe

utf8_decode 368

VValiditätsprüfung 351Value-Konvertierung 348VARCHAR 586Variable Funktionen 472Variablen

globale 63Qualifier 72

Variablendeklaration 27Variablenfunktionen 103Variablennamen 69Varying Character 586VBA 411Vererbung 105, 117verifyPassword (PEAR) 248Verkettete Listen 330Veröffentlichen von Flash-Filmen 360Versionsnummer 506Versionsnummern 317Verständlichkeit des Codes 55Verzeichnisstruktur 509Visual Basic for Applications 411Volltextsuche 601Vorausschauen 388vorletzter Fehler 269Vulnerability 446

WWagenrücklauf 33WARNING 146Warteschlangen 329Watchdog 285Watches 291Whitespaces 33wordwrap (Smarty) 205Workaround 61Workbook 250Workbook � s. Arbeitsmappe

Worksheet 250Worksheet � s. ArbeitsblattWrapper-Funktionen 101write (PEAR) 251writeBlank (PEAR) 253writeFomula (PEAR) 253writeNumber (PEAR) 252writeString (PEAR) 253writeUrl (PEAR) 253Wurzel 331

XXdebug 548xdebug_dump_function_profile 549,

551xdebug_dump_function_trace 554xdebug_get_function_profile 553xdebug_get_function_trace 554xdebug_start_profiling 549xdebug_stop_profiling 549xdigit, POSIX-Klasse 385XML_Tree (PEAR) 260XP 273X-Priority 426XSS 458XX_DEBUG_ON 281

ZZahlenformat 537Zeichenklassen 382Zeichensätze 405Zeilenvorschub 33Zeitleiste 356, 363Zeitzonen 522Zend Optimizer 295Zend Performance Suite 569Zend Server Center 555Zend Studio 17Zugriffslogfiles 181Zurückschauen 388

620 Index