Sandini Bib
PHP
Sandini Bib
Sandini Bib
MASTER CLASS
Andreas Barchfeld
PHP
Einstieg für Anspruchsvolle
ADDISON-WESLEY
[ in Kooperation mit ]
Sandini Bib
Bibliografische Information Der Deutschen Bibliothek Die Deutsche Bibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über http://dnb.ddb.de abrufbar. Die Informationen in diesem Buch werden ohne Rücksicht auf einen eventuellen Patentschutz veröffentlicht. Warennamen werden ohne Gewährleistung der freien Verwendbarkeit benutzt. Bei der Zusammenstellung von Texten und Abbildungen wurde mit größter Sorgfalt vorgegangen. Trotzdem können Fehler nicht ausgeschlossen werden. Verlag, Herausgeber und Autoren können für fehlerhafte Angaben und deren Folgen weder eine juristische Verantwortung noch irgendeine Haftung übernehmen. Für Verbesserungsvorschläge und Hinweise auf Fehler sind Verlag und Herausgeber dankbar. Alle Rechte vorbehalten, auch die der fotomechanischen Wiedergabe und der Speicherung in elektronischen Medien. Die gewerbliche Nutzung der in diesem Produkt gezeigten Modelle und Arbeiten ist nicht zulässig. Fast alle Hardware- und Softwarebezeichnungen, die in diesem Buch erwähnt werden, sind gleichzeitig auch eingetragene Warenzeichen oder sollten als solche betrachtet werden. Umwelthinweis: Dieses Produkt wurde auf chlorfrei gebleichtem Papier gedruckt.
10 9 8 7 6 5 4 3 2 1 08 07 06 05
ISBN 3-8273-2181-6
© 2005 Pearson Studium, ein Imprint der Pearson Education Deutschland GmbH, Martin-Kollar-Straße 10–12, D-81829 München/Germany Alle Rechte vorbehalten www.pearson-studium.de Lektorat: Frank Eller,
[email protected] Einbandgestaltung: Marco Lindenbeck, webwo GmbH (
[email protected]) Herstellung: Elisabeth Prümm,
[email protected] Satz: mediaService, Siegen (www.media-service.tv) Druck und Verarbeitung: Kösel, Krugzell (www.KoeselBuch.de) Printed in Germany
Sandini Bib
Inhaltsverzeichnis Vorwort Kapitel 1 Installation und Konfiguration 1.1 XAMPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 Binärinstallation für den IIS. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2.1 PHP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2.2 IIS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3 Binärinstallation Apache/PHP unter Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.1 Installation des Apache-Servers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.2 Konfiguration des Apache-Servers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.3 Apache auf der Befehlszeile (auch als Dienst) . . . . . . . . . . . . . . . . . . . . . . . 1.4 Installation aus den Quellcode-Dateien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.4.1 Apache-Installation unter Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.4.2 PHP-Installation unter Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.4.3 PHP-Installation unter Windows. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.5 PEAR-Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.5.1 Installation per Browser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.5.2 Kommandozeilen-Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Kapitel 2 Erste Schritte 2.1 Was ist PHP? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.1 Ein Überblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Programmaufruf. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3 Aufbau eines Skripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Kapitel 3 Variablen und ihre Datentypen 3.1 3.2 3.3 3.4 3.5 3.6
11 15 15 17 17 20 23 23 28 37 41 42 45 49 57 58 63
67 68 68 70 76
97
Überblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 Was ist eine Variable? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 Variablennamen. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 Variable Variablennamen. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 Vordefinierte Variablen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 Konstante Werte. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
5
Sandini Bib Inhaltsverzeichnis
3.7 3.8 3.9 3.10 3.11
3.12 3.13 3.14
3.15 3.16 3.17 3.18 3.19 3.20
3.21
6
Variablendeklaration. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . PHP-Datentypen – eine Übersicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Der logische Datentyp BOOLEAN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Logische Operatoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Vergleichsoperatoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.11.1 Die Operatoren > und >= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.11.2 Die Operatoren < und
All die bisher gezeigten Formen haben entweder Einschränkungen oder benötigen Änderungen in der Datei php.ini. Vielfach haben Sie aber keinen Einfluss darauf, welche Tags gestattet sind, gerade wenn Sie Webseiten bei einem Hosting-Anbieter betreiben. Die Variante, die garantiert immer gültig ist, ist die speziell für diese Skriptart gültige Form, die so genannte kanonische Form. Listing 2.9 Die kanonische Form
Sie haben jetzt die verschiedenen Möglichkeiten gesehen, wie man ein Skript aufrufen kann. Aber wie bindet man dies nun in eine HTML-Seite ein? Werfen Sie einen Blick auf Listing 2.10: Listing 2.10 PHP-Aufruf innerhalb einer HTML-Seite
PHP im HTML Aufruf eines PHP-Skripts
Die HTML-Seite wird angezeigt.
72
Sandini Bib Programmaufruf
und hier ist wieder HTML
Wenn Sie diese Seite im Publikationsverzeichnis Ihres Webservers abgespeichert haben, beispielsweise als html01.php, können Sie diese Seite mit jedem Browser aufrufen. In dem Moment lädt der Server die Seite, um sie über das Netz an Ihren Browser zu schicken. Der Server stellt fest, dass es sich um eine Skript-Datei handelt. Zu diesem Zeitpunkt nimmt er den Text zwischen dem Start- und dem Stopp-Tag und übergibt diesen Text dem Programm, das für diese Tags verantwortlich ist, in unserem Fall also PHP. PHP nimmt den Text entgegen und interpretiert ihn nach seinen Regeln. Das Ergebnis liefert er dem Webserver zurück, der das Ergebnis dann an die Stelle der Tags setzt. In diesem Beispiel wird eine Funktion echo() aufgerufen. Diese Funktion macht nichts anderes, als den Text „Hier spricht PHP“ auszugeben. Da keine weitere Anweisung in dem PHPSkript steht, ist dieser Text die Rückgabe des PHP-Interpreters an den Webserver. Content-type: text/html
Listing 2.11 HTML-Seite für den Browser
X-Powered-By: PHP/5.0.0
PHP im HTML
73
Sandini Bib 2 Erste Schritte
Listing 2.11 (Forts.) HTML-Seite für den Browser
Aufruf eines PHP-Skripts
Die HTML-Seite wird angezeigt.
Hier spricht PHP
und hier ist wieder HTML
Das Ergebnis dieser Aktion ist in Listing 2.11 zu sehen. Wie Sie sehen, ist das PHP-Skript verschwunden. Übrig geblieben ist die Zeichenkette, die nun als normaler HTML-Text auf der Seite erscheint. Die Darstellung im Browser ist in Abbildung 2.1 dargestellt. Abbildung 2.1 Browserdarstellung des Listing 2.10
In der Version 4.2.0 von PHP wurde eine weitere Verarbeitungsform für Skripte eingeführt, die CLI-Funktionalität. Mit CLI können Skripte auf der Kommandoebene ausgeführt werden. Die Abkürzung CLI steht für Command Line Interface. Mit der Version 4.3.0 von PHP wurde dieses Feature zum offiziellen Bestandteil der Sprache PHP. Bei dieser Form des Programmaufrufes brauchen Sie sich um HTML keine Gedanken zu machen. Ein CLI-Skript verarbeitet die Daten und gibt das Ergebnis in einem Kommandofenster aus. In Windows ist dies das cmd-Fenster, in Linux die Shell-Ebene. In Listing 2.12 sehen Sie ein einfaches Skript, das als CLI-Programm ausgeführt werden kann.
74
Sandini Bib Programmaufruf
Dieses Skript gibt nur eine Zeichenkette aus. Gestartet wird ein solches Programm, indem Sie den PHP-Interpreter am Kommandoprompt, gefolgt von dem Dateinamen des Skripts, eingeben. In Abbildung 2.2 sehen Sie den Aufruf des Programms sowie dessen Ausgabe. Abbildung 2.2 Ausgabe des Listing 2.12
Mit dieser Art der Programmierung können vollkommen andere Programmtypen erstellt werden, die früher der Batch-, Shell- oder Perl-Programmierung vorbehalten waren. So kann man PHP heute zum Beispiel auch für die Erstellung von Systemverwaltungstools benutzen. Am Ende dieses Abschnittes zeige ich Ihnen nun noch ein „sonderbares“ Skript. Es ist ein Exot und nicht sehr ausbaufähig. Werfen Sie einen Blick auf Listing 2.13. Ein sonderbares Skript
Listing 2.13 Ein sonderbares Skript
Dieses Skript hat keine Start- und Stopp-Tags, keinen PHP-Befehl. Es besteht nur aus einer Zeichenkette, die zudem nicht einmal in Anführungszeichen steht. Speichern Sie dieses Skript unter dem Namen sonderbar.php ab. Wenn Sie dieses Skript jetzt mit einem Browser öffnen, wird Ihnen der Text angezeigt. Nun könnte man meinen, dass der Webserver dies als einfachen HTML-Text erkennt und entsprechend ausgibt. Dem ist aber nicht so. Dies können Sie testen, indem Sie dieses Skript auf der Kommandoebene ausführen. Das Ergebnis sehen Sie in Abbildung 2.3. Zur Bestätigung, dass es sich wirklich um diese Zeile handelt, wurde das Programm zuerst mit dem Befehl type ausgegeben. Direkt anschließend wird das Programm aufgerufen. Als Ergebnis wird die Zeichenkette ausgegeben!
75
Sandini Bib 2 Erste Schritte
Abbildung 2.3 Ausgabe des sonderbaren Skripts
Sie sehen hier ein Feature von PHP: PHP ist eine interpretierende Sprache! Nicht nur in dem Sinne, wie wir es weiter oben besprochen haben, sondern noch auf einer anderen Ebene. PHP versucht zu interpretieren, was Sie wohl meinen. Ein solches Verhalten kann in manchen Situationen zu Fehlern führen, die schlecht zu erkennen sind. In diesem Beispiel handelt der PHP-Interpreter sicherlich in Ihrem Interesse. Aber da er keine Gedanken lesen kann, wird es Programmsituationen geben, wo er Sie falsch interpretiert – wenn Sie ihm nicht unmissverständlich gesagt haben, was Sie wollen. Eine durchaus alltägliche Situation. Sie sollten also genau den Aufbau eines PHP-Skripts kennen.
2.3
Aufbau eines Skripts
Im letzten Abschnitt haben wir erste Programme erstellt, ohne uns groß mit PHP selbst auseinander zu setzen. Woraus besteht ein PHP-Programm – abgesehen von den Start- und Stopp-Tags? Grob kann man ein Programm, auch Skript genannt, in mehrere Stufen aufteilen: Ein Skript besteht aus einer Anweisung oder einer Abfolge von Anweisungen. Eine Anweisung besteht aus einem Ausdruck oder einer Abfolge von Ausdrücken. Ein Ausdruck kann für sich stehen oder das Ergebnis einer Anweisung sein. Es gibt spezielle Ausdrücke, Token genannt. Unter Token versteht man spezielle Sprachelemente einer Programmiersprache, wie zum Beispiel if – then – else. Diese Token werden wir im Verlaufe der Einführung noch kennen lernen.
76
Sandini Bib Aufbau eines Skripts
Ein Ausdruck kann eine Zeichenkette, eine Zahl, eine Konstante sein. Ein Ausdruck hat immer einen Wert. Dieser Wert kann zahlenmäßig 0 (Null) oder eine leere Zeichenkette "" sein. Wenn Sie sich die obige Aufzählung anschauen, besteht ein minimalistisches Programm einzig und allein aus einem Ausdruck. Ein ähnliches Programm mit einer Zahl als Ausdruck wäre dann beispielsweise: 42
Listing 2.14 Eine Zahl als Ausdruck
Abgesehen von der Tatsache, dass diese Zahl die Antwort auf die Frage aller Fragen ist, kann man mit einem solchen Programm aber noch nicht viel anfangen. Da man mit einfachen Zahlen das Verhalten des Interpreters sehr gut zeigen kann, beschränken wir uns erst einmal auf diese Ausdrücke. Um mehrere Ausdrücke zu einer sinnvollen Anweisung zusammenzufügen, muss dem Interpreter mitgeteilt werden, wie diese Ausdrücke verknüpft werden. Bei Zahlen kann dies beispielsweise durch das Token für die Addition geschehen:
Wenn Sie dieses Programm ausführen, sehen Sie in der Ausgabe nichts, da PHP nicht erkennen kann, was Sie mit dieser Anweisung bezwecken wollen. In PHP gibt es eine große Menge von zusammengesetzten Ausdrücken, Funktionen genannt, die Sie ohne weitere Vorkehrungen einsetzen können. Eine dieser Funktionen haben Sie schon kennen gelernt: echo. Wir kommen auf das Thema Funktionen noch detailliert zu sprechen. An dieser Stelle soll diese Erklärung zu Funktionen erst einmal reichen. Die Funktion echo gibt das zurück, was Sie dieser Funktion übergeben haben. Aber wie in der Natur sich das Echo anders anhören kann, kann das Echo einer Funktion durch PHP interpretiert sein.
Listing 2.15 Der erste richtige zusammengesetzte Ausdruck aus 01.php
In Listing 2.15 sehen Sie den ersten „richtigen“ zusammengesetzten Ausdruck, eine Anweisung. Beachten Sie, dass am Ende der Zeile ein „;“
77
Sandini Bib 2 Erste Schritte
steht. Dies ist klammheimlich hinzugefügt worden. Der Grund liegt in einer Regel von PHP: Jede Anweisung wird mit einem Semikolon beendet. Bei der Ausführung dieses Programms versucht PHP, unsere Absicht zu erkennen. Wollen wir den zusammengesetzten Ausdruck „1 + 1“ als Zeichenkette „1 + 1“, oder soll das Ergebnis der Rechenoperation „1 +1“ ausgegeben werden? Der Test beweist: PHP entscheidet sich für die Rechenoperation: Abbildung 2.4 Ergebnis von Listing 2.15
Kommen wir auf die Aussage zurück, dass jede Anweisung mit einem Semikolon enden muss. PHP ist sehr großzügig, was die Interpretation so genannter „White Spaces“ angeht. Unter diesem Begriff sind nicht nur Leerzeichen gemeint, sondern auch Zeichen wie Tabulator oder Zeilenumbruch. So können Sie bequem eine lange Anweisung auf mehrere Zeilen aufteilen. Ein etwas extremes Beispiel ist in Listing 2.16 zu sehen. Listing 2.16 Eine Anweisung über mehrere Zeilen aus 02.php
In diesem Beispiel wird die recht einfache Anweisung aus Listing 2.15 auf mehrere Zeilen aufgeteilt. Wenn Sie dieses Programm ausführen, erhalten Sie exakt das gleiche Ergebnis wie in Abbildung 2.4. Für PHP ist die Anweisung erst am Semikolon beendet, egal welche und wie viele White Spaces sich über die Anweisung verteilen. Es gibt aber Grenzen dieser Aufteilung. So können Sie Namen von Funktionen oder Token nicht auseinander reißen. In Listing 2.17 sehen Sie einen solchen fehlerhaften Umbruch.
78
Sandini Bib Aufbau eines Skripts
PHP kann die Funktion einer Fehlermeldung:
Listing 2.17 Fehlerhafter Umbruch
echo
nicht mehr erkennen, und es kommt zu Abbildung 2.5 Fehlermeldung aus Listing 2.17
Auf der anderen Seite können Sie durch das Semikolon aber auch mehrere Anweisungen in eine Zeile schreiben. Dies sollten Sie aber nur bei einfachen Anweisungen machen, da darunter die Lesbarkeit des Codes nachlässt. Ein Beispiel sehen Sie in Listing 2.18.
Listing 2.18 Zwei Anweisungen in einer Zeile
Die Ausgabe dieses Programms entspricht aber sicher nicht dem im ersten Augenblick erwarteten Ergebnis: die Zahl 2 in einer Zeile und die Zahl 4 in der darauf folgenden Zeile. Abbildung 2.6 Das Ergebnis aus Listing 2.18
79
Sandini Bib 2 Erste Schritte
Die beiden Zahlen werden direkt hintereinander ausgegeben und liefern sichtlich ein nicht gewünschtes Ergebnis. Zu dem gleichen Ergebnis kommen Sie auch, wenn Sie die beiden Anweisungen in separate Zeilen schreiben. Was dem Interpreter fehlt, ist die Anweisung, in die nächste Zeile zu gehen. Und hier haben Sie einen Unterschied zwischen der Web- und der CLIVersion von PHP. Wie Sie sicherlich wissen, erzwingen Sie in HTML einen Zeilenumbruch durch die Angabe von . In der CLI-Version wird dies nicht als Zeilenumbruch erkannt. Sie müssen ein spezielles White-Space-Zeichen benutzen: \n. C- und C++-Programmierer werden dieses Zeichen sofort erkennen. \n besteht augenscheinlich aus zwei Zeichen, dem „\“ und dem „n“. PHP interpretiert aber diese Kombination der beiden Zeichen als „Zeilenumbruch“ von Textausgaben. Betrachten wir hierzu das Listing 2.19: Listing 2.19 Zeilenumbruch in PHP
Zuerst wird das Ergebnis der Addition von 1 + 1 ausgegeben, also 2. Es folgt in der nächsten Zeile das Zeichen für den CLI-Zeilenumbruch. Wie die Zeichenkette „Hier spricht PHP“ aus Listing 2.10 handelt es sich um eine normale Zeichenkette. Würden Sie das Zeichen „\“ vor dem „n“ weglassen, würde PHP an dieser Stelle den Buchstaben „n“ ausgeben. Nach der Addition von 2 + 2 wird der HTML-Zeilenumbruch ausgegeben, gefolgt von der Addition der Zahlen 3 + 3. Wenn Sie das Programm auf der Kommandozeile starten, erhalten Sie das Ergebnis aus Abbildung 2.7. Das Zeichen \n wird als Zeilenumbruch erkannt. Die Zeichenkette „“ wird nicht interpretiert, sondern als solche ausgegeben. Hier interpretiert PHP richtig. Sie haben das Programm nicht über einen Browser, sondern über die Kommandozeile gestartet.
80
Sandini Bib Aufbau eines Skripts
Abbildung 2.7 CLI-Ausgabe von Listing 2.19
Starten Sie das Programm mit einem Browser, so erhalten Sie die Ausgabe von Abbildung 2.8. Auch hier hat PHP richtig interpretiert. Da Sie das Programm über einen Browser gestartet haben, erkennt er zwar den Zeilenumbruch \n, behandelt ihn aber wie jeden anderen Zeilenumbruch eines HTML-Quelltextes, nämlich gar nicht. Nun ist es nicht sehr häufig, dass ein Skript sowohl im Browser als auch auf Kommandozeilenebene ausgeführt werden soll. Sollte es dennoch vorkommen, muss man allerdings nicht zwei Versionen des gleichen Skripts schreiben. An dieser Stelle sei ein kleiner Vorgriff erlaubt. Mit PHP kann man feststellen, welcher Browser das Skript aufgerufen hat. Es soll ja Unterschiede zwischen verschiedenen Browsern geben. Wird ein Programm nicht mit einem Browser gestartet, kann man diesen nicht feststellen. Also muss das Programm über die Kommandozeile gestartet worden sein. Abbildung 2.8 HTML-Ausgabe von Listing 2.19
81
Sandini Bib 2 Erste Schritte
Die Lösung besteht also aus einem Stück Code, das der Logik folgt: Listing 2.20 Pseudoprogramm zum Zeilenumbruch
Wenn Browser erkennbar dann "" sonst "\n"
Das entsprechende PHP-Programm ist in Listing 2.21 zu sehen. Wie Sie sehen, ist die Wenn–dann-sonst-Pseudoanweisung fast wortwörtlich ins Englische übersetzt worden – und eine gültige PHP-Anweisung. Listing 2.21 Angepasster Zeilenumbruch aus 06.php
In beiden Zweigen dieser Anweisung wird einem Ausdruck $crlf die jeweils gültige Zeichenkette für einen Zeilenumbruch übergeben. Im weiteren Verlauf des Programms wird dieser Ausdruck dann dazu benutzt, den richtigen Zeilenumbruch auszugeben. Abbildung 2.9 Ergebnis aus Listing 2.21
82
Sandini Bib Aufbau eines Skripts
Dieser Ausdruck, $crlf, ist nicht Bestandteil der Programmiersprache PHP. Der Name ist frei erfunden, wenn auch ziemlich passend. Diese Art von Ausdrücken wird als Platzhalter benutzt, die man im weiteren Verlauf des Programms an so ziemlich jeder Stelle benutzen kann. Da diesen Ausdrücken eine besondere Stellung zukommt, tragen sie auch eine eigene Bezeichnung: Es sind so genannte Variablen. Variablen müssen in PHP immer mit einem $-Zeichen beginnen. Dies ist für den Interpreter das Signal, hier folgt ein durch den Programmierer frei definierter Platzhalter. Nach dem $-Zeichen folgt der eigentliche Variablenname, sozusagen die Adresse des Platzhalters. Dieser Variablenname muss mit einem Buchstaben oder dem Unterstrich „_“ beginnen. Alle anderen Zeichen sind nicht erlaubt. Nach diesem ersten Zeichen können alle Zeichen des erweiterten ASCII-Zeichensatzes benutzt werden. Zusätzlich kommt hinzu, dass bei Variablennamen ein Unterschied zwischen Groß- und Kleinschreibung gemacht wird. Die Variablen $var01 und $Var01 bezeichnen zwei vollkommen unterschiedliche Platzhalter, können also auch unterschiedliche Werte haben. Die folgende Tabelle zeigt einige Variablennamen und ihre Gültigkeit: Variable
Gültig
$result
Ja
$Result
Ja, aber andere Variable als oben
$_vari
Ja
$res01
ja
$_§301
Ja
$1plus2
Nein
$ähnlich
Ja, sollte man aber bei internationaler Verbreitung vermeiden
$vari-1
Nein
$#fh
Nein
Tabelle 2.1 Variablennamen
In Listing 2.22 sehen Sie ein kleines Programm, das zwei Variablen deklariert, aber in unterschiedlicher Schreibweise.
Wenn Sie dieses Programm ausführen, erhalten Sie als Ergebnis die Ausgabe: Listing 2.23 Ergebnis des Listing 2.22
5 7
Sie sollten einen solche Variablennamen vermeiden, da die Verwechslung auf der Hand liegt. Die Wahrscheinlichkeit, dass Sie sich bei der Programmierung vertun, ist sehr hoch. Und wenn Sie sich Ihr Programm nach einigen Monaten nochmals anschauen, werden Sie bei einer solchen Wahl von Variablennamen eher schwer tun. Dies gilt in besonderem Maße für andere Personen, die sich Ihr Programm anschauen wollen. Damit kommen wir zwanglos zu einem weiteren Punkt. Wählen Sie sprechende Namen. Die Zeiten, in denen Variablennamen nur aus einem Buchstaben oder vielleicht nur aus sieben Buchstaben bestehen durften, sind vorbei. Mit Variablen kann man aber nicht nur Werte zwischenspeichern. Mit ihnen lassen sich auch beispielsweise weitere Berechnungen durchführen. Listing 2.24 Berechnung mit Variablen
In Listing 2.24 wird die Anzahl von Patienten der Variablen $patient_count übergeben. Anschließend folgt die Übergabe der Anzahl Eltern an die Variable $parent_count. Diese beiden Variablen werden nun dazu verwendet, der neuen Variablen $total_customer die Summe dieser beiden Variablen zuzuordnen. Das Ergebnis wird anschließend mit der echo-Funktion ausgegeben.
84
Sandini Bib Aufbau eines Skripts
Bisher haben wir in den Skripten entweder mit Zahlen (ganz speziell sogar mit „ganzen Zahlen“) oder mit Zeichenketten gearbeitet. Wer sich schon einmal mit einer anderen Programmiersprache beschäftigt hat (C/C++, C#, VB.NET, COBOL), wird sich sicher schon gefragt haben, woher PHP weiß, wann es sich um eine Zahl und wann um eine Zeichenkette handelt. An keiner Stelle im Programm wurde PHP direkt gesagt, „die Variable mit dem Namen $var01 kann nur ganze Zahlen aufnehmen“. PHP gehört zu den so genannten „typenlosen Sprachen“. Die Programmiersprache PERL gehört ebenfalls in diese Kategorie. Das heißt nicht, dass es überhaupt keine Typen gibt. Intern arbeitet PHP durchaus mit verschiedenen Typen. Aber in vielen Fällen müssen Sie sich darüber keine Gedanken machen. Die Fälle, bei denen Sie sich Gedanken machen sollten, werden im nächsten Kapitel behandelt. Man könnte an dieser Stelle auf die Idee kommen und sagen: „Ist doch klar! Mit der ersten Zuweisung wird festgelegt, welcher Typ erlaubt ist.“ Schauen Sie sich das nächste Listing an:
In Listing 2.25 wird der Variablen $mixed erst der Wert 5 zugeordnet und ausgegeben. Anschließend wird in dieser Variablen eine Zeichenkette abgespeichert. Achten Sie bei der Zeichenkette auf das führende „\n“. Auf diese Weise wird die Zeichenkette in der nächsten Zeile des Bildschirms ausgegeben. Das dieses Programm einwandfrei ausgeführt wird, können Sie anhand der Abbildung 2.10 sehen:
85
Sandini Bib 2 Erste Schritte
Abbildung 2.10 Ergebnis aus Listing 2.25
Zuerst wird die Zahl 5 ausgegeben, anschließend ohne Fehlermeldung der Text. Eine Variable kann also im Verlaufe eines Programms unterschiedliche Typen beherbergen. Diese Flexibilität geht sogar noch weiter. Man kann mit verschiedenen Typen rechnen! Und hier wird es dann Zeit, sich bei komplexeren Programmen den einen oder anderen Gedanken vor der Programmierung zu machen. Ansonsten erreicht man schnell das Chaos. Werfen Sie einen Blick auf Listing 2.26. Listing 2.26 Verarbeitung verschiedener Typen
Es wird eine Variable angelegt, die mit der Zahl 5 nummerisch belegt wird. Die zweite Variable wird mit der Zeichenkette „10“ belegt, also einem Typ, der erst einmal mit einer Zahl recht wenig gemeinsam hat. Im nächsten Schritt wird dann die Zeichenkette zur Zahl addiert! Jede typstarke Programmiersprache würde an dieser Stelle die Zusammenarbeit verweigern. PHP versucht an dieser Stelle wieder nicht nur die Sprache, sondern auch Ihre Wünsche zu interpretieren. Und diese Anweisung sieht nach einer gewollten Addition zweier Zahlen aus. Intern verwandelt PHP die Variable $string_value in eine Zahl und addiert diese mit der Variablen $numeric_value. Schlussendlich wird das Ergebnis der Berechnung – 15 – ausgegeben, siehe Abbildung 2.11.
86
Sandini Bib Aufbau eines Skripts
Im Laufe dieser Übersicht haben wir den echo-Befehl für die Ausgabe von Zahlen als auch für die Ausgabe von Zeichenketten benutzt. Will man die Anzeige von Variableninhalten etwas benutzerfreundlicher gestalten, so kann man diese Variable in eine Zeichenkette einbetten.
In Listing 2.27 sehen Sie hierfür ein Beispiel. Die Variable $tax erscheint zwischen den beiden Anführungszeichen der Zeichenkette. Wenn Sie dieses Programm ausführen, erhalten Sie die Ausgabe: Der Mehrwertsteuersatz liegt bei 16 %
Bei der Ausführung des Programms kontrolliert PHP den Inhalt dieser Zeichenkette und ersetzt den Variablennamen durch den Inhalt dieser Variablen. Abbildung 2.11 Addition von Zahl und Zeichenkette
Bis zu diesem Zeitpunkt haben wir in unseren Beispielen immer mit festen Werten gearbeitet. So wurde die Addition zweier Zahlen in Listing 2.26 mit den festen Werten $numeric_value und $string_value durchgeführt. Es wäre aber recht umständlich, würde man für jede Änderung einer Rechengröße das Programm umschreiben müssen. Eine Möglichkeit, einem Programm Werte zu übermitteln, kennen Sie wahrscheinlich aus Ihrer Arbeit mit Windows oder Linux. Dort können Sie einem Programm Werte auf der Kommandozeile übergeben. Um sich
87
Sandini Bib 2 Erste Schritte
beispielsweise eine besondere Darstellungsart eines Inhaltsverzeichnisses anschauen zu können, werden dem entsprechenden Befehl so genannte Argumente mit auf den Weg gegeben. In Windows lautet der Befehl zur verkürzten Darstellung eines Verzeichnisses dir /w. In Linux kann man sich im Gegensatz dazu ein Verzeichnislisting in der Langform mit ls –l anschauen. Hier werden dem jeweiligen Programm also über die Angabe von Argumenten Informationen über die Darstellung mitgeteilt. Diese Form der Datenübergabe kann auch in PHP benutzt werden, wenn Sie Werte bei dem Programmstart über die Kommandozeile übergeben wollen (CLI). Zu diesem Zweck existieren in PHP zwei Variablen, argc und argv. Wer schon das eine oder andere C-Programm gesehen hat, kennt diese beiden Variablen sicherlich. Diese beiden Variablen werden immer beim Start eines Programms erstellt, wenn Sie in der php.ini den dafür vorgesehenen Schalter aktivieren: Listing 2.28 php.ini-Eintrag für argc und argv
register_argc_argv = On
Aus Performancegründen ist dieser Schalter normalerweise auf Off eingestellt. Wenn Sie die kleinen Programme dieses Kapitels nachvollziehen, werfen Sie an dieser Stelle erst einen Blick in die Datei php.ini. Sie sollten Ihren eigenen Variablen natürlich nicht identische Namen geben. Wie werden diese beiden Variablen nun dazu genutzt, dem Programm Werte zu übergeben? Werfen Sie hierfür einen Blick auf Listing 2.29: Listing 2.29 Programm mit Übergabe-Argumenten
Erst einmal wird eine Überschrift ausgegeben. Mit „\n“ wird vor und nach der Überschriftenzeile eine Freizeile ausgegeben. Die Anzahl der übermittelten Argumente wird in der Variablen $argc (argument count) hinterlegt. Diese Information benötigen Sie für die Variable $argv (argument vector). Bei dieser Variablen handelt es sich
88
Sandini Bib Aufbau eines Skripts
um eine spezielle Art von Variablen. Wir werden im Laufe des Buches noch detailliert darauf zurückkommen. Es handelt sich um eine Variablenart, die mit einem Namen mehrere Werte aufnehmen kann, man spricht auch von Vektoren oder Arrays. Die Zählung der verschiedenen Werte beginnt immer bei null, wobei das nullte Argument ($argv[0]) immer der Name des gestarteten Programms ist. Das erste Argument ($argv[1]) ist damit auch der erste von Ihnen an das Programm übergebene Wert. Achten Sie darauf, dass die Zahl nach und ] – eingeschlossen ist.
$argv
in eckigen Klammern – [
Wenn Sie sicherstellen wollen, dass auch wirklich die exakte Anzahl von Argumenten an das Programm übergeben wird, können Sie dies mit $argc überprüfen. In Listing 2.30 sehen Sie ein Beispiel für eine solche Überprüfung.
Hier begegnet Ihnen auch wieder die if-Abfrage. Wenn die Anzahl der übergebenen Argumente nicht gleich 3 ist, gebe eine Meldung aus und beende das Programm. Die Zeichenfolge != steht bei einem solchen Vergleich also für „nicht gleich“. Es gibt noch eine ganze Zahl weiterer solcher Vergleichsoperatoren, zum Beispiel == für „gleich“. Wir kommen darauf noch zu sprechen. Mit exit() sehen Sie eine so genannte „interne Funktion“. Wie Sie vermuten werden, gibt es demnach auch noch „externe Funktionen“. Unter Funktionen kann man sich so etwas wie Unterprogramme vorstellen, also Programme innerhalb von Programmen.
89
Sandini Bib 2 Erste Schritte
Die Funktion exit() sorgt dafür, dass bei einem Fehler das Programm frühzeitig verlassen wird. Einen solchen fehlerhaften Aufruf von Listing 2.30 sehen Sie in Abbildung 2.12. Abbildung 2.12 Programmaufruf mit fehlenden Argumenten
Rufen Sie das Programm mit der richtigen Anzahl an Argumenten auf, wird nicht in diesen Zweig des Programms gesprungen, sondern die Verarbeitung beginnt nach der if-Anweisung. Sie sehen hier auch, dass mehrere Anweisungen nach einer if-Abfrage stehen können. Diese müssen dann mit „{„ und „}“ eingeklammert werden. Im weiteren Verlauf des Programms werden die beiden Übergabeargumente addiert und auf dem Bildschirm ausgegeben. Wie ein solcher Programmlauf auf dem Bildschirm aussieht, sehen Sie in Abbildung 2.13. Bei der Übergabe von Argumenten müssen Sie darauf achten, dass die Typen der Argumente für die Verarbeitung auch stimmen. Wenn Sie also statt der Zahl „8“ beispielsweise die Zeichenkette „acht“ übergeben, erhalten Sie das Ergebnis in Abbildung 2.14. Abbildung 2.13 Programmaufruf mit Argumenten
90
Sandini Bib Aufbau eines Skripts
Abbildung 2.14 Programmaufruf mit falschem Übergabetyp
Es wird kein Fehler gemeldet, sondern „nur“ falsch gerechnet. Für den richtigen Typ sind Sie als Programmierer verantwortlich. Was ist aber mit Programmen, die eine unbestimmte Zahl von Argumenten übernehmen können? Denken Sie an die Verzeichnisbefehle von Linux und Windows. An dieser Stelle kommen Schleifen ins Spiel. Bei einer Schleife handelt es sich bekanntermaßen um eine Abfolge von Anweisungen, die mehrere Male ausgeführt werden. Wie oft, hängt von den äußeren Bedingungen der jeweiligen Schleife ab. In dem obigen Beispiel haben Sie $argc-Argumente an das Programm übergeben. Um alle Argumente zu betrachten, muss man also $argc-mal einen Blick in die Variable $argv werfen. In solchen Fällen setzt man so genannte „zählergesteuerte Schleifen“ ein. In PHP werden solche Schleifen durch die Befehlsfolge for (...) eingeleitet. Listing 2.31 zeigt Ihnen die Anwendung einer solchen Schleife mit $argc und $argv.
91
Sandini Bib 2 Erste Schritte
Bevor wir auf diese Schleifenkonstruktion eingehen, schauen Sie sich die Abbildung 2.15 an. Dem Programm werden beim Start fünf Argumente übergeben: „Am“, „Anfang“, „war“, „das“ und „Wort“. Nach einer Überschrift und der Angabe, wie viele Argumente an das Programm übergeben wurden, geht das Programm sofort in die Schleife. Eine zählergesteuerte Schleife benötigt drei Angaben: 1. Wo beginnt die Schleife? 2. Wann endet die Schleife? 3. Wie wird in der Schleife hoch gezählt? Diese drei Angaben finden Sie durch Semikolons getrennt in der Klammer der for-Anweisung. Damit die Schleife auch zählen kann, wird eine Hilfsvariable benutzt. Diese kann jeden beliebigen, gültigen Namen haben. Aus der Historie der Programmierung haben sich die Buchstaben i, j, k für solche Fälle erhalten. Wir wollen uns alle Argumente anschauen, daher beginnt die Hilfsvariable $i bei null. Die Schleife endet, wenn die Hilfsvariable nicht mehr kleiner als der Wert von $argc ist. Anders ausgedrückt, solange die Hilfsvariable kleiner als ein Grenzwert ist, wird die Schleife abgearbeitet. Der Grenzwert ist in diesem Beispiel die Variable $argc. Es gibt sechs Übergabeargumente: $argv[0] bis $argv[5]. Abbildung 2.15 Beispiel für eine zählergesteuerte Schleife
Die Abfolge von Anweisungen innerhalb der Schleife wird wie bei der if-Anweisung in geschweifte Klammern eingebettet.
92
Sandini Bib Aufbau eines Skripts
Es gibt in PHP nicht nur die zählergesteuerten Schleifen. Neben foreach, einer speziellen Form der zählergesteuerten Schleife, gibt es noch die while-Schleife. Wie der Name vermuten lässt, handelt es sich um eine Schleife, die so lange durchlaufen wird, wie ein Ausdruck (in diesem Fall auch Bedingung genannt) gültig ist. Man kann jede for-Schleife in eine while-Schleife umwandeln. Der umgekehrte Weg ist nicht immer gangbar. Um die for-Schleife aus Listing 2.31 in eine solche while-Schleife zu verwandeln, müssen nicht viele Punkte geändert werden. Schauen Sie sich dazu Listing 2.32 an.
Um die zählergesteuerte Schleife zu implementieren, benötigen wir einen Zähler, der außerhalb der while – Schleife initialisiert wird. Dies muss natürlich vor dem Eintritt in die Schleife geschehen. Im Listing 2.32 wird hierzu die Variable $i mit null initialisiert. Wie schon erwähnt, sollte man keine kryptischen Variablennamen verwenden. Da an dieser Stelle die Variable aber nur für die Schleife benötigt wird, also in einem überschaubaren Rahmen, und gleichzeitig $i eine klassische Zählervariable darstellt, kann man den Gebrauch hier durchaus rechtfertigen. Die Bedingung für die while-Schleife entspricht der Bedingung der zählergesteuerten Schleife: Solange die Variable $i dem Wert von $argc nicht entspricht oder sogar übersteigt, wird die Schleife ausgeführt. Damit die Schleife also irgendwann abbricht, muss innerhalb der Schleife dafür gesorgt werden, dass die Schleifenbedingung nicht mehr gilt. In unserem Beispiel wird dies dadurch erreicht, dass die Zählervariable $i jeweils um 1 hochgezählt wird.
93
Sandini Bib 2 Erste Schritte
Das Ergebnis von Listing 2.32 entspricht im Übrigen der Abbildung 2.15. So war es ja auch geplant. Der letzte Punkt, der in diesem kleinen Rück- und Überblick noch fehlt, um das Bild vollständig zu machen, ist die Übergabe von Werten an ein PHP-Programm über einen Webbrowser. Schauen Sie sich dazu das reine HTML-Listing 2.33 an. Es handelt sich um ein Formular im puren HTML. Im -Tag geben Sie der Webseite mit, welches Programm ausgeführt werden soll, wenn Sie den Submit-Button anklicken. Die Methode, die hier gewählt wurde, ist die so genannte POST-Methode. Listing 2.33 HTML-Formular-Seite zur Addition zweier Zahlen: add.html
Eingabe von Daten per Formular Bitte geben Sie zwei nummerische Werte zur Addition ein:
1. Zahl
2. Zahl
Es werden zwei Zahlen als Text eingelesen. HTML kennt keine nummerischen Datentypen. Bei HTML ist alles Text. Diese Zahlen bekommen jeweils einen Namen, „zahl1“ und „zahl2“, damit man später auf die Werte zugreifen kann. Der Button zum Abschicken des Formulars bekommt den Namen „okay“ und die Beschriftung „Okay“.
94
Sandini Bib Aufbau eines Skripts
Abbildung 2.16 HTML-Eingabeformular zur Addition zweier Zahlen
In Abbildung 2.16 sehen Sie das Formular aus Listing 2.33. Wenn Sie in dieses Formular zwei Zahlen einfügen und den OKAY-Button anklicken, werden die Daten an das Skript „add.php“ weitergeleitet. Dieses Skript muss wie die Datei „add.html“ (Listing 2.33) im Dokumentenordner Ihres Webservers stehen. Den Aufbau der Datei add.php finden Sie in Listing 2.34. Sie beginnen mit einer normalen Webseite. Um nun die Formulardaten zu lesen, beginnen Sie einen Abschnitt mit dem Tag
$result;
95
Sandini Bib 2 Erste Schritte
Wenn Sie sich den Namen genauer anschauen, so stellen Sie fest, dass es sich bei dem Unterstrich um ein erlaubtes Zeichen für einen Variablennamen handelt. Auch Sie können Variablennamen mit einem Unterstrich beginnen lassen (siehe Tabelle 2.1). Es handelt sich bei der Variablen $_POST also um den gleichen Typ von Variablen wie bei $argv. Es gibt einen kleinen Unterschied: In $argv hatten wir zwischen den eckigen Klammern reine Zahlen. Bei der Variablen $_POST stehen zwischen den eckigen Klammern keine Zahlen, sondern die Namen der HTML-Werte in einfachen Hochkomma-Zeichen. Es handelt sich um Zeichenketten, die sich etwas von den bekannten Zeichenketten unterscheiden, die durch doppelte Hochkomma-Zeichen begrenzt werden. Um den Unterschied etwas zu verdeutlichen, werden diese HTML-Werte in PHP-Variablen kopiert. Und anschließend normal addiert. Nach der Ausgabe des Ergebnisses durch den Befehl echo wird der PHPTeil verlassen und in diesem Beispiel auch anschließend der HTML-Teil des Skripts. Das Ergebnis dieses Skripts finden Sie in Abbildung 2.17. Sie sehen zuerst den Satz aus dem HTML-Teil des Skripts, direkt gefolgt von der Ausgabe des echo-Befehls. Abbildung 2.17 Ergebnisseite des Programms add.php
Nachdem Sie Ihre Kenntnisse über PHP in diesem Kapitel aufgefrischt oder sich einen Überblick verschafft haben, gehen wir im nächsten Kapitel näher auf die Datentypen von PHP ein und riskieren dabei einen Blick in das interne Vorgehen von PHP.
96
Sandini Bib
Variablen und ihre Datentypen 3.1
Überblick
In diesem Kapitel beschäftigen wir uns mit dem grundlegenden Stoff, ohne den selbst kleine Programme nicht auskommen – mit den Variablen und ihren zugeordneten Datentypen. Sie werden sehen, welche verschiedenen Arten von Variablen es in PHP gibt und wie man mit ihnen arbeiten kann. Dabei werden wir auf die Variablen eingehen, die Sie im Verlaufe eines Programms erstellen und nutzen können, aber auch auf die von PHP automatisch erstellten Variablen. Wo es Variablen, also veränderliche Größen gibt, liegt die Vermutung nahe, dass es auch so etwas wie unveränderliche Größen gibt. Diese werden als Konstanten bezeichnet. Die Definition und Verwendung dieser Größen wird uns in diesem Kapitel ebenfalls beschäftigen. Bei den Datentypen werden wir uns die in PHP zur Verfügung stehenden Datentypen ansehen. Die Besonderheiten der jeweiligen Datentypen spielen in der Programmierung an so mancher Stelle eine entscheidende Rolle. Einen Punkt werden wir speziell betrachten: Wie funktioniert die Umwandlung von einem Datentyp in einen anderen? Der Effekt der automatischen Typenkonvertierung ist zugleich Fluch und Segen einer derart konzipierten Programmiersprache.
3.2
Was ist eine Variable?
Wie Sie schon im vorigen Kapitel gesehen haben, werden Variablen dazu benutzt, Informationen/Daten zwischenzuspeichern, damit man im Verlauf des Programms auf diese Größe zugreifen und damit arbeiten kann. Mit dem Begriff speichern ist in diesem Zusammenhang aber
97
Sandini Bib 3 Variablen und ihre Datentypen
nicht die Festplatte oder CD/DVD gemeint, sondern der Hauptspeicher des Rechners. In dieser Beschreibung steckt im Grunde schon die genaue Definition eines solchen Sprachkonstruktes. Eine Variable zeichnet sich durch folgende Punkte aus: Eine Variable hat einen Namen hat mindestens einen Wert, und sei er NULL belegt Speicherplatz im Hauptspeicher des Rechners hat einen Datentyp In anderen Programmiersprachen bedeutet NULL im wahrsten Sinne des Wortes „nichts“. Sie können dann mit dieser Variablen auch nicht arbeiten. Sie bekommen dann einen Fehler gemeldet. In PHP könnten Sie mit einer solchen Variablen arbeiten.
3.3
Variablennamen
Ein Variablenname besteht aus einer Abfolge von Buchstaben, Zahlen und dem Zeichen Unterstrich. Dabei wird bei den Buchstaben zwischen Groß- und Kleinschreibung unterschieden. Da die Darstellung von Buchstaben auf unterschiedliche Art und Weise geschehen kann, ASCII, UniCode etc., muss noch festgelegt werden, welche Zeichenkodierung in PHP benutzt wird. Aus der Historie heraus handelt es sich um den ASCII-Zeichensatz. Bei diesem Zeichensatz wird für jeden Buchstaben, jede Zahl oder jedes Sonderzeichen nur ein Byte benutzt. Aber nicht alle ASCII-Zeichen eignen sich für einen Variablennamen. So ist das ASCIIZeichen 13 das Signal für einen Zeilenvorschub. Ein Variablenname muss mit dem „$“-Zeichen beginnen. Nach dem $ können Sie Großbuchstaben (ASCII-Zeichen 65 bis 90), Kleinbuchstaben (ASCII-Zeichen 97 bis 122), den Unterstrich (ASCII-Zeichen 95) und Teile des erweiterten Zeichensatzes (ASCII-Zeichen 127 bis 255) benutzen. Der erweiterte Zeichensatz ermöglicht es Ihnen, auch Sonderzeichen als Bestandteil des Namens zu verwenden. So ist es möglich, einen Variablennamen mit deutschen Umlauten zu erstellen. $Ätzflüssigkeit = 1;
98
Sandini Bib Variablennamen
So gestaltete Variablennamen sollten Sie aber nur dann einsetzen, wenn Sie sich sicher sind, dass Ihr Programm nur innerhalb des deutschsprachigen Raumes gelesen wird. Das Programm wird auch in Amerika oder Frankreich laufen, aber die dort eingesetzten Editoren werden statt der Umlaute komplett andere Zeichen darstellen. Das trägt nicht zur Verständlichkeit des Programms bei. Name
Erlaubt/Bemerkung
$mwst
Ja
$MwSt
Ja/andere Variable als $mwst
$Ähnlichkeitsfaktor
Ja
$5Karat
Nein/kein Buchstabe nach dem $
$_
Ja
$_zustand1
Ja
$_1a
Ja/erstes Zeichen ein _
Einkauf
Nein/es fehlt das $-Zeichen
$xyz
Ja
$wk1859
Ja
Tabelle 3.1 Gültige und ungültige Variablennamen
In Tabelle 3.1 sehen Sie einige gültige und ungültige Variablennamen. Dabei fällt Ihnen sicherlich auf, dass Sie mit einigen Namen eine Vorstellung verbinden, was die Bedeutung dieser Variablen sein könnte, so zum Beispiel bei der Variable $MwSt. Andere Namen sind nicht ganz so verständlich. Was versteckt sich hinter der Variablen $_ oder hinter der Variablen $_1a? Handelt es sich bei der letzteren um eine Variable für den Zustand, wenn ja, von was? Oder ist damit ein Verarbeitungsschritt gemäß einer ISO 9000-Zertifizierung gemeint? In Listing 3.1 sehen Sie ein anderes Extrem zum Thema Variablennamen. Sie sehen wahrscheinlich sofort, welche Berechnung hier durchgeführt wird. Hier wurden zwar sprechende Variablennamen benutzt, doch die Aussage dieser Namen trägt nicht zum Verständnis des Programms bei. Variablennamen sollten nicht nur sprechend sein, sondern auch eine zutreffende Aussage über den Inhalt oder die Bedeutung einer Variablen beinhalten.
99
Sandini Bib 3 Variablen und ihre Datentypen
Listing 3.1 Was wird berechnet?
Übrigens, in Listing 3.1 wird die Mehrwertsteuer von 1000 Euro berechnet. Haben Sie’s erkannt? Dieses Beispiel mag unwahrscheinlich klingen. Aber nicht ganz so extreme Fälle kann man in der freien Wildbahn beobachten, durchaus auch bei größeren Programmsystemen. Als Variablenname eignet sich in vielen Fällen ein beschreibendes Hauptwort oder eine knappe Umschreibung des Zustandes, den die Variable festhält. Abkürzungen sind nur dann sinnvoll, wenn man davon ausgehen kann, dass sie von fast allen Personen verstanden werden. Gerade bei Open-Source-Projekten mit wechselnden Programmierern ist dies problematisch. Aber auch wenn nur Sie sich mit dem Programm beschäftigen, sollten Sie dafür sorgen, dass Sie Ihr Programm auch noch dann verstehen, wenn Sie mehrere Monate nicht auf den Quelltext geschaut haben. Sie sollten sich auch angewöhnen, Ihre Variablen immer nach ein und demselben Schema zu benennen. Es haben sich hauptsächlich zwei Schreibweisen etabliert. Wenn Sie einen Variablennamen aus mehreren Wörtern zusammensetzen wie im obigen Beispiel bei der Variablen $nettoflussgeschwindigkeit, so können Sie die Lesbarkeit erhöhen, wenn Sie im Namen jedes Wort mit einem Großbuchstaben beginnen: $NettoFlussGeschwindigkeit
oder zwischen jedem Wort einen Unterstrich einfügen: $netto_fluss_geschwindigkeit
Welche Form der Namensgebung Sie auch wählen, Sie sollten diese Form in Ihrem Programm konsequent beibehalten.
100
Sandini Bib Variable Variablennamen
Was Sie in PHP-Programmen eher selten finden, ist eine Erweiterung dieser Schreibweise, wie man sie früher in C-Programmen für Windows fand. Dort hatte man ein Präfix für einen Datentyp vor dem eigentlichen Variablennamen. Handelte es sich bei einer Variablen beispielsweise um eine nummerische Variable, so wurde ein „n“ vorangestellt, bei einer Zeichenkette ein „sz“. So hat man neben dem Namen ein weiteres Kriterium, mit welchen Variablen man es zu tun hat. $szName = "Müller"; $nTitle = 5;
Listing 3.2 Erkennbarkeit falscher Zuordnung durch Typpräfix
$szName = $nTitle;
Wenn Sie einen Blick in das Listing 3.2 werfen, können Sie erkennen, dass in der letzten Zeile sehr wahrscheinlich ein Fehler steckt, auch wenn der eigentliche Name der Variablen, Title, etwas anderes vermuten lässt. Zusätzlich könnte man vermuten, dass der Name nicht sehr geschickt gewählt wurde.
3.4
Variable Variablennamen
Bei den bisherigen Beispielen haben wir einer Variablen immer einen Wert zugewiesen, sei dies nun ein nummerischer Wert oder eine Zeichenkette. Weitere Datentypen werden Sie im Folgenden noch genau kennen lernen. Was liegt näher, als den Namen einer Variablen ebenfalls zu einer Variablen zu machen? Das heißt, Sie können mit einer Variablen auf die Namen anderer Variablen zugreifen. Schauen Sie sich Listing 3.3 einmal genau an.
In der ersten Zeile wird der Variablen $name der Nachname übergeben. Direkt im Anschluss wird der Vorname in der Variablen $name_chr abgespeichert. So weit ist alles bekannt. Die nächste Zeile sieht auf den ersten Blick ebenfalls noch normal aus. Eigentlich ist sie das auch, aber: In der Variablen mit dem Namen $variable_name wird der Name einer neuen Variablen festgelegt. Diese Variable soll den Namen „dyn_var“ bekommen. Festgelegt wird dies in der nächsten Zeile. Achten Sie auf die doppelten „$“-Zeichen am Beginn der Zuweisung. Sie können Sich das Verhalten dieser Zuweisung klar machen, indem Sie im Kopf den „inneren Namen“ einklammern und durch die so benannte Variable ersetzen. In diesem Beispiel müssen Sie also im Kopf zuerst Listing 3.4 Pseudobefehl zum Namensersatz bei dynamischen Variablen
$variable_name = "dyn_var" $$variable_name = $ ( $variable_name ) $$variable_name = $ ( dyn_var ) $$variable_name = $dyn_var
in Gedanken die Klammern wie in Listing 3.4 setzen. Innerhalb der Klammern erkennen Sie die Variable $variable_name. Der Wert dieser Variablen ist die Zeichenkette „dyn_var“. Wenn Sie nun diese Zeichenkette in die Klammer einsetzen und anschließend die Klammern im Kopf wieder entfernen, haben Sie die Bedeutung dieser Zuweisung. In der Variablen $dyn_var finden Sie den Wert, der in der Variablen $$variable_name zu finden ist. Zurück zu Listing 3.3. Nach der Zuweisung $$variable_name = $name;
finden Sie in der Variablen Nach der Zuweisung
$dyn_var
den Inhalt der Variablen
$name.
$$variable_name = $name_chr;
befindet sich der Wert der Variablen $dyn_var.
$name_chr
in der Variablen
In Abbildung 3.1 sehen Sie das Ergebnis eines Programmlaufs von Listing 3.3.
102
Sandini Bib Vordefinierte Variablen
Abbildung 3.1 Beispiel dynamischer Variablen aus Listing 3.3
Einen kleinen Nachtrag müssen wir an dieser Stelle machen: In allen vorangegangenen Beispielen wurde das =-Zeichen benutzt. Aus der Mathematik erinnert man sich vielleicht, dass dieses Zeichen für die Gleichheit steht: 1 + 1 = 2. Die linke Seite der Gleichung entspricht der rechten Seite. In fast allen Computersprachen gilt dies nicht! Das =-Zeichen gilt hier als Zuweisung. Der linken Seite wird das zugewiesen, was auf der rechten Seite des =-Zeichens steht. Sie können also ohne weiteres schreiben: $wert = $wert + 1;
Dies ist mathematisch falsch. In PHP bedeutet es nichts anderes, als dass der Wert der Variablen $wert um eins erhöht und anschließend dieser Variablen wieder zugewiesen wird. Der alte Wert der Variablen ist damit verschwunden.
3.5
Vordefinierte Variablen
Wie Sie in den vorangegangenen Abschnitten gesehen haben, können Sie eine Variable nach Ihren Wünschen erstellen (zu den Datentypen kommen wir gleich). Aber Sie haben auch schon gesehen, dass es Variablen gibt, die Sie nicht erstellt haben, die aber dennoch vorhanden und für Sie nutzbar waren: $argc und $argv. Dies sind aber bei weitem nicht alle Variablen, die Ihnen PHP vorgibt. In Versionen vor PHP 4.0.3 mussten Sie hierfür eine Einstellung in der Konfigurationsdatei php.ini ändern. Aus Sicherheitsgründen ist der Schalter seit dieser Version im Standard immer eingeschaltet. Es handelt sich um den Konfigurationsparameter track_vars. Sollten Sie mit einer PHP-Version arbeiten, die älter ist, sollten Sie dringend auf eine neuere Version wechseln. Ist dies nicht möglich, ändern Sie in der Datei php.ini den Parameter gemäß Listing 3.5.
103
Sandini Bib 3 Variablen und ihre Datentypen
Listing 3.5 Einstellung in der Konfigurationsdatei für vordefinierte Variable
Tabelle 3.2 Gruppennamen vordefinierter Variablen, ebenfalls Variable
track_vars="On"
Die Menge der vordefinierten Variablen ist so umfangreich, dass man sie thematisch zusammengefasst hat. In Tabelle 3.2 sind die Variablen aufgeführt, in denen die eigentlichen Variablen der jeweiligen Gruppe gespeichert sind. Es handelt sich um so genannte assoziative Arrays, eine Variablenart, die Sie im Anschluss noch genauer betrachten werden. Diese Variablen werden auch Superglobals genannt. Diese Variablen können Sie von jeder Stelle Ihres Skripts aus aufrufen, daher auch der Name. Variablenliste
Inhalt
$_COOKIE
Eine Liste mit Variablen, die dem Programm über HTTP übermittelt wurden
$_ENV
Eine Liste mit Variablen, welche die Werte der Betriebssystemumgebung enthält
$_FILES
Eine Liste mit Variablen, die Informationen über hochgeladene Dateien enthält
$_GET
Eine Liste mit Variablen, die dem Skript über die GET-Methode von HTTP übermittelt wurden
$GLOBALS
Eine Liste mit den in dieser Tabelle dargestellten Variablen
$_POST
Eine Liste mit Variablen, die dem Skript über die POSTMethode von HTTP übermittelt wurden
$_REQUEST
Eine Liste aller Variablen, die auf irgendeinem Weg vom Anwender an das Programm übermittelt wurden (nicht bei der Kommandozeile): $_GET, $_POST, $_COOKIE
$_SESSION
Eine Liste von Variablen, die zu einer Session gehören
$_SERVER
Eine Liste von Variablen, die vom zuständigen Web-Server an das Skript übermittelt werden
$argc
Kommandozeile: die Anzahl der Übergabeparameter
$argv
Kommandozeile: Liste mit Variablen, die als Argument auf der Kommandozeilenebene dem Programm übergeben wurden
Um sich einen Überblick über all diese Variablen zu verschaffen, gibt es einen ebenfalls vordefinierten Unterprogrammaufruf - get_defined_ vars(). In Listing 3.6 wird dieser Aufruf dazu genutzt, alle Superglobals in der Variablen $bekannte_variable zu speichern. Auf ähnliche Weise können Sie mit allen Variablen aus Tabelle 3.2 verfahren.
104
Sandini Bib Vordefinierte Variablen
In der zweiten Zeile wird der Inhalt der Superglobal-Variablen $_SERVER mit einem neuen Befehl print_r ausgegeben. Dieser Befehl zeigt Informationen über einen Ausdruck an. In diesem Fall handelt es sich um eine Variable. Bei komplizierteren Ausdrücken werden alle Informationen rekursiv ausgegeben. Die Ausgabe von Listing 3.6 können Sie in Listing 3.7 sehen. Array ( [include] => C:\Programme\Microsoft Visual Studio\VC98\atl \include; C:\Programme\Microsoft Visual Studio\VC98\mfc \include; C:\Programme\Microsoft Visual Studio\VC98\include [PROMPT] => $P$G [SESSIONNAME] => Console [ALLUSERSPROFILE] => C:\Dokumente und Einstellungen\All Users [OS] => Windows_NT [ComSpec] => C:\WINDOWS\system32\cmd.exe [HOMEPATH] => \Dokumente und Einstellungen\Barchfeld [APPDATA] => C:\Dokumente und Einstellungen\Barchfeld\ Anwendungsdaten [TEMP] => C:\DOKUME~1\BARCHF~1\LOKALE~1\Temp [PROCESSOR_ARCHITECTURE] => x86 [XDEBUG_CONFIG] => remote_handler=gdb [USERNAME] => Barchfeld [SystemDrive] => C: [PROCESSOR_REVISION] => 0905 [COMPUTERNAME] => DVLP01 [VCToolkitInstallDir] => C:\Programme\Microsoft Visual C++ Toolkit 2003\ [PROCESSOR_IDENTIFIER] => x86 Family 6 Model 9 Stepping 5, GenuineIntel [USERDOMAIN] => DVLP01 [USERPROFILE] => C:\Dokumente und Einstellungen\Barchfeld [lib] => C:\Programme\Microsoft Visual Studio\VC98\mfc\lib; C:\Programme\Microsoft Visual Studio\VC98\lib [windir] => C:\WINDOWS [LOGONSERVER] => \\DVLP01 [CommonProgramFiles] => C:\Programme\Gemeinsame Dateien
Listing 3.7 Ausgabe von Listing 3.6
105
Sandini Bib 3 Variablen und ihre Datentypen
[PATHEXT] => .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH [CLIENTNAME] => Console [MSDevDir] => C:\Programme\Microsoft Visual Studio\ Common\MSDev98 [SystemRoot] => C:\WINDOWS [ProgramFiles] => C:\Programme [HOMEDRIVE] => C: [DBGP_COOKIE] => workbench77 [Path]=> C:\WINDOWS\system32;C:\WINDOWS; C:\WINDOWS\system32\WBEM; C:\Programme\Gemeinsame Dateien\GTK\2.0\bin; C:\Programme\Support Tools\; C:\PHP; C:\Programme\Microsoft Visual Studio\Common \Tools\WinNT; C:\Programme\Microsoft Visual Studio\Common \MSDev98\Bin; C:\Programme\Microsoft Visual Studio\Common\Tools; C:\Programme\Microsoft Visual Studio\VC98\bin [PROCESSOR_LEVEL] => 6 [NUMBER_OF_PROCESSORS] => 1 [TMP] => C:\DOKUME~1\BARCHF~1\LOKALE~1\Temp [REQUEST_METHOD] => GET [SCRIPT_FILENAME] => dummy.php [QUERY_STRING] => start_debug=1&debug_port=10000&debug_host=127.0.0.1 [REDIRECT_STATUS] => 1 [ORIG_PATH_TRANSLATED] => dummy.php [ORIG_PATH_INFO] => dummy.php [ORIG_SCRIPT_FILENAME] => dummy.php [PHP_SELF] => [argv] => Array ( [0] => start_debug=1&debug_port=10000&debug_host=127.0.0.1 )
Listing 3.7 (Forts.) Ausgabe von Listing 3.6
[argc] => 1 )
Die Informationen werden in einem Array dargestellt. Wenn Sie eine komplette Aufstellung haben wollen, müssen Sie die Einschränkung auf $_SERVER entfernen. In der fünften Zeile der Ausgabe finden Sie die Abkürzung OS. Hierbei handelt es sich um den Eintrag für das Betriebssystem. Wenn Sie diese einzelne Information benötigen, müssen Sie das Programm leicht verändern. Im folgenden Listing ist diese Änderung durchgeführt. Die Variable wird nicht sofort ausgegeben, sondern der neuen Variablen $betriebssystem
106
Sandini Bib Konstante Werte
zugeordnet. Für die Ausgabe der Variablen hätten Sie an dieser Stelle auch den Befehl echo verwenden können.
Wir werden uns mit dieser speziellen Art von Variablen in dem Kapitel über Arrays noch näher beschäftigen. Wo es veränderliche Werte gibt, sind in vielen Fällen auch konstante Werte nicht weit.
3.6
Konstante Werte
Bis zum jetzigen Zeitpunkt haben wir zur Zwischenspeicherung von Werten immer Variablen genutzt. Nun gibt es aber auch Werte, die sich im Laufe eines Programms nicht ändern. Dies kann unterschiedliche Ursachen haben. So gibt es Zahlen, von denen wir mit ziemlicher Sicherheit sagen können, dass es sich um konstante Zahlen handelt. Hierunter fallen beispielsweise die Kreiszahl PI (p) oder die Euler´sche Zahl „e“ (rund 2.71828). Weiterhin gibt es so genannte physikalische Konstanten, von denen wir annehmen, dass sie in unserem Universum konstant sind, beispielsweise die Gravitationskonstante. Auf jeden Fall sind diese beiden Arten von Konstanten länger konstant, als unsere Programme existieren werden. Dann gibt es noch Werte, die über einen längeren Zeitraum als konstant angenommen werden können. Aber auch diese Werte können im Laufe der Lebenszeit des Programms Änderungen erfahren. Hiezu zählt beispielsweise die Mehrwertsteuer. Auf jeden Fall sind diese Werte konstanter als die Zwischensumme einer Rechnung. Bei solchen Zahlen muss man sich entscheiden, ob man diese Werte in einem Programm veränderlich lässt oder als Konstante definiert. Dies hängt vom Zweck des Programms ab und muss vom Programmierer individuell entschieden werden.
107
Sandini Bib 3 Variablen und ihre Datentypen
Schauen Sie sich Listing 3.9 an. Dort wird der Umfang eines Kreises berechnet. Dazu benötigen Sie die Kreiszahl PI, die in der ersten Zeile als Variable eingesetzt wird. Listing 3.9 Kreisberechnung mit falscher Konstanten
Wenn Sie dieses Programm starten, wird es Ihnen den Kreisumfang mit 34.55749
berechnen. Nun hindert Sie keiner daran, im weiteren Verlauf des Programms eine solche „Konstante“ zu verändern, da Sie sie ja als veränderlich definiert haben. Besser wäre es, eine solche Veränderung nicht zuzulassen. Dies erreichen Sie, indem Sie dem PHP-Interpreter mitteilen, eine Änderung dieses Wertes nicht zuzulassen. Dafür benutzen Sie die Anweisung define. In Listing 3.10 sehen Sie die Anwendung dieser Anweisung für die Zahl PI. Listing 3.10 Kreisberechnung mit definierter eigener Konstanten
Nach dem Wort define wird in Klammern zuerst der Name der Konstanten und anschließend, durch Komma getrennt, der Wert dieser Konstanten festgelegt. In PHP hat es sich durchgesetzt, alle Konstanten durchgehend mit Großbuchstaben zu schreiben. Achten Sie auch auf die Zeile, in der der Kreisumfang ($kreis_umfang) berechnet wird. Die Konstante wird ohne führendes $-Zeichen geschrieben!
108
Sandini Bib Konstante Werte
Da die Zahl PI, wie auch weitere mathematische Größen, durchaus in PHP benötigt werden – denken Sie an die Berechnung von Tortengrafiken –, gibt es in PHP einige vordefinierte Konstanten. Eine Auswahl finden Sie in Tabelle 3.3.
Mit dieser vordefinierten Konstanten wird die Kreisberechnung zu der in Listing 3.11 gezeigten Form. Zusätzlich finden Sie auch noch die Ausgabe einer weiteren Konstanten, der Zeilennummer __LINE__. Bei dieser und den anderen Konstanten – programmbezogene Konstanten – handelt es sich um Werte, die zumindest für den Lauf eines Programms konstant sind. Wenn Sie dieses Programm laufen lassen, wird Ihnen Hier ist Zeile 7 Der Kreisumfang beträgt: 34.557519189488
angezeigt. Name
Beschreibung
__LINE__
Die aktuelle Zeilennummer einer Datei.
__FILE__
Der vollständige Pfad- und Dateiname einer Datei.
Tabelle 3.3 Einige vordefinierte Werte
__FUNCTION__ Der Name einer Funktion. Steht seit PHP 4.3.0 zur Verfügung. __CLASS__
Der Name einer Klasse. Steht seit PHP 4.3.0 zur Verfügung.
__METHOD__
Der Name einer Klassenmethode. Steht seit PHP 5.0.0 zur Verfügung.
M_PI
Die Kreiszahl p
M_E
Die Euler´sche Zahl e
109
Sandini Bib 3 Variablen und ihre Datentypen
3.7
Variablendeklaration
In den vergangenen Beispielen haben wir Variablen einen Wert zugewiesen, eine Zeichenkette oder Zahl ohne eine Deklaration zu machen. Wenn Sie sich schon mit einer anderen Programmiersprache beschäftigt haben, werden Sie dieses Feature bisher vergeblich gesucht haben. Sie werden es auch weiterhin nicht finden. PHP ist eine typenlose Sprache. Das heißt, auf den ersten Blick gibt es keine Datentypen in PHP. Der Typ einer Variablen wird bei der Zuweisung eines Wertes festgelegt. Aber nicht endgültig. Schauen Sie sich dazu einmal Listing 3.12 an. Zuerst wird der Variablen $wert die Ganzzahl 2 zugewiesen und ausgegeben. Anschließend wird dieser Variablen die Zahl 2.1415 übergeben. In einer Sprache wie C oder C# kann dies zu Fehlermeldungen des Compilers führen. Spätestens bei der nächsten Wertzuweisung würden Sie Probleme bekommen. Eine Zeichenkette ist eigentlich keine Zahl. Listing 3.12 Verschiedene Typen in einer Variablen
Dieses Programm kann unter PHP fehlerfrei ausgeführt werden und liefert Ihnen: Die Variable wert hat den Inhalt: 2 Die Variable wert hat den Inhalt: 2.1415 Die Variable wert hat den Inhalt: Hallo Welt.
PHP geht sogar so weit, dass Sie das Programm aus Listing 3.13 einwandfrei ausführen können. Wenn Sie dieses Programm ausführen, erhalten Sie als Ergebnis die Ausgabe: Die Variable wert hat den Inhalt: 3
110
Sandini Bib Variablendeklaration
Bei der Behandlung von Datentypen weiter unten werden wir uns mit diesem Thema beschäftigen.
Der PHP-Interpreter meldet standardmäßig auch nicht, wenn Sie sich vertippen und so eine Variable benutzen, die es eigentlich in Ihrem Programm nicht gibt. Ein solcher Effekt ist in Listing 3.14 vorhanden.
Es wird eine Variable $name mit der Zeichenkette „Ute“ besetzt. In der Ausgabe wird allerdings die Variable $namen benutzt. Wenn Sie dieses Programm laufen lassen, bekommen Sie die Ausgabe Der Name lautet:
Dies ist sicherlich nicht beabsichtigt. Es gibt drei Möglichkeiten, dieses Problem zu beheben. In der Datei php.ini gibt es einen Eintrag, der sich mit der Behandlung von Fehlern beschäftigt. Es handelt sich um den Eintrag error_reporting
=
E_ALL & ~E_NOTICE & ~E_STRICT
Sie können diesen Eintrag in die Form von Listing 3.16 bringen. Es werden Ihnen dann alle Fehler und Warnungen ausgegeben, die der PHPInterpreter finden kann. Dies geschieht zur Laufzeit! error_reporting
=
E_ALL
Durch die Änderung in der Datei php.ini gilt diese Änderung natürlich für alle PHP-Programme, die auf dem Server laufen. Dies ist in manchen Fällen nicht gewünscht. Zudem benötigen Sie den Zugriff auf diese Datei. Wenn Sie Ihre Seiten bei einem Internet.Hosting.Provider betreiben, wird Ihnen diese Möglichkeit sehr wahrscheinlich nicht zur Verfügung stehen.
Listing 3.15 Standardfehlereintrag in der Datei php.ini
Listing 3.16 Eintrag in php.ini zur Anzeige aller Fehler
111
Sandini Bib 3 Variablen und ihre Datentypen
Sie können diese Einstellung aber auch zur Laufzeit des Programms verändern. In Listing 3.17 wird die zurzeit gültige Ebene der Fehlermeldung in der Variablen $old_error_status gespeichert. Listing 3.17 Veränderung der Fehlereinstellung im Skript
Gleichzeitig wird in der Zeile die neue Fehlerebene auf die vordefinierte Konstante E_ALL gesetzt. Die Funktion error_reporting() liefert Ihnen die zum Zeitpunkt des Aufrufes gültige Fehlerebene. Wenn Sie den alten Stand wiederherstellen wollen, können Sie dies wieder mit der Funktion error_reporting() machen. Sie müssen nur die Variable für den alten Wert der Fehlerebene an die Funktion übergeben. Auf diese Weise können Sie kritische Bereiche Ihres Programms sozusagen einklammern. Die Ausgabe des Programms aus Listing 3.17 sehen Sie in Abbildung 3.2. Abbildung 3.2 Programmaufruf mit E_ALL und nicht deklarierter Variablen
Wenn Sie den Fehler beheben und das Programm nochmals aufrufen, erhalten Sie die Ausgabe von Abbildung 3.3.
112
Sandini Bib Variablendeklaration
In der Programmentwicklungsphase sollten Sie dies nutzen, um möglichst früh auf Probleme mit dem Programm aufmerksam gemacht zu werden. Wenn Sie Daten vom Browser an Ihr Programm übergeben, kann dieser Effekt nicht gewünscht sein, da Sie aufgrund der Tatsache, ob eine Variable gesetzt ist oder nicht, über das weitere Vorgehen im Programm entscheiden. In diesem Fall können Sie die PHP-Funktion isset() benutzen, um auf nicht deklarierte Variablen zu testen. Allerdings reicht in vielen Fällen diese Funktion noch nicht aus. In Listing 3.18 sehen Sie die Anwendung dieser Funktion. Abbildung 3.3 Programmaufruf mit geklammertem E_ALL
Wenn Sie dieses Programm ausführen, werden Ihnen beide echo-Zeilen ausgegeben. Die erste Ausgabe dürfte klar sein, die Variable $name ist mit der Zeichenkette „Ute“ deklariert. Die Ausgabe der zweiten echo-
113
Sandini Bib 3 Variablen und ihre Datentypen
Zeile basiert auf der Tatsache, dass in diesem Fall die Variable ebenfalls einen Wert hat – die leere Zeichenkette. Die Funktion empty() führt eine erweiterte Prüfung durch. Hat die Variable den Wert 0 oder "", so liefert diese Funktion den Wert true zurück. In Listing 3.19 sehen Sie die Anwendung dieser Funktion auf eine leere Zeichenkette und eine Variable mit dem Zahlenwert 0 als Inhalt. Listing 3.19 Anwendung der Funktion empty()
Das Programm liefert Ihnen als Ausgabe Der Name ist leer. Zahl ist 0 oder leer.
Die Ursache für das Verhalten von PHP bei nicht deklarierten Variablen liegt an einer sehr einfachen Regel: Findet der PHP-Interpreter eine nicht deklarierte Variable, so versucht er, einen Wert für diese Variable aus dem direkten Umfeld der Variablen festzulegen. Handelt es sich um eine Verarbeitung von Zeichenketten, so wird die Variable mit der Zeichenkette "" angelegt. Handelt es sich um eine mathematische Berechnung, so bekommt die Variable den Wert 0. Womit wir zwanglos bei den Datentypen angelangt sind.
114
Sandini Bib PHP-Datentypen – eine Übersicht
3.8
PHP-Datentypen – eine Übersicht
Obwohl PHP als datentypenlose Sprache gilt, arbeiten Sie selbstverständlich mit verschiedenen Arten von Daten. Bisher haben wir hauptsächlich mit zwei Typen gearbeitet, den ganzen Zahlen, auch Integer genannt, und den Zeichenketten, auch Strings genannt. Insgesamt gibt es aber acht Datentypen, die nochmals in drei Gruppen aufgeteilt werden. Vier skalare Typen: Typ
Beschreibung
Bool
Die Werte true oder false/wahr oder falsch
Integer
Ganze Zahlen: 1, 2, 45, 100, 1000, -34
Tabelle 3.4 Die skalaren Datentypen
Fließkomma/Floating Point Gebrochen rationale Zahlen: 3.14, 5.6, 0.333, –5.6 Zeichenkett/String
Zeichenketten: „D“, „Test“, „Hallo Welt“
Zwei zusammengesetzte Typen: Typ
Beschreibung
Array
Geordnete Abbildung
Objekt
Datentyp, der Wert und Verhalten vereinigt
Tabelle 3.5 Die zusammengesetzten Datentypen Array und Objekt
Zwei spezielle Typen: Typ
Beschreibung
Resource
Spezieller Typ für z.B. File-Handler, Datenbank-Handler etc.
NULL
Nicht gesetzte Variable
Tabelle 3.6 Die speziellen Datentypen Resource und NULL
Wir werden uns diese Datentypen und ihr Verhalten im Folgenden genauer betrachten. Datentypen intern
PHP ist in C programmiert. Die Sprache C ist aber datentypenorientiert. Ein Blick in den Quellcode von PHP sei an dieser Stelle gestattet. Der Wert und Datentyp einer Variablen wird in PHP in der folgenden Datenstruktur abgelegt:
115
Sandini Bib 3 Variablen und ihre Datentypen
Listing 3.20 Definition einer PHPVariablen in C
struct _zval_struct { /* Variable information */ zvalue_value value; /* value */ zend_uint refcount; zend_uchar type; /* active type */ zend_uchar is_ref; };
Der eigentliche Wert einer Variablen wird in dem gemeinsamen Speicherbereich zvalue_value abgelegt: Listing 3.21 Darstellung eines PHPVariablenwertes in C
typedef union _zvalue_value { long lval; /* long value */ double dval; /* double value */ struct { char *val; int len; } str; HashTable *ht; /* hash table value */ zend_object_value obj; } zvalue_value;
Man erkennt, dass Integerwerte intern als C-long-Werte behandelt werden. Fließkommazahlen werden intern als C-double behandelt, beides Datentypen mit dem für C größten Wertebereich. Zeichenketten werden nicht als klassische C-Zeichenketten behandelt, sondern es wird die Länge der Zeichenkette mitgeführt. In der Struktur findet sich auch der gerade aktive Datentyp, der zum gespeicherten Wert gehört – sonst wäre es auch schwierig, auf zvalue_value richtig zuzugreifen. Die Datentypen sind definiert als: /* data #define #define #define #define #define #define #define #define #define #define
types */ IS_NULL0 IS_LONG1 IS_DOUBLE2 IS_STRING3 IS_ARRAY4 IS_OBJECT5 IS_BOOL6 IS_RESOURCE7 IS_CONSTANT8 IS_CONSTANT_ARRAY9
Man sieht, dass PHP intern mit zehn Datentypen arbeitet. Wer sich näher mit diesem Aufbau beschäftigen möchte, sollte einen Blick in die Datei zend.h werfen.
116
Sandini Bib Der logische Datentyp BOOLEAN
Vielfach findet man in der Literatur den Hinweis, dass PHP je nach Prozessorarchitektur einen unterschiedlich großen Wertebereich für Integerwerte hat – bedingt durch das Verhalten von C in diesem Bereich. Ein Blick in den Quellcode beantwortet diese Frage. Ebenfalls in der Datei zend.h finden Sie die Zeilen: #ifndef LONG_MAX #define LONG_MAX 2147483647L #endif #ifndef LONG_MIN #define LONG_MIN (- LONG_MAX - 1) #endif
Damit sind der größte und der kleinste Integerwert in PHP festgelegt. Da der Datentyp einer Variablen im Laufe eines Programms geändert werden kann, muss man eine Möglichkeit haben, im Bedarfsfall den Typ einer Variablen feststellen zu können. Von welchem Typ ist die Variable zum Verarbeitungszeitpunkt? Für diese Problemstellung gibt es die Funktion gettype(). Umgekehrt kann man mit der Funktion settype() den Typ explizit setzen. gettype() ist aber nicht die einzige Funktion, mit der man etwas über den Datentyp einer Variablen erfahren kann.
3.9
Der logische Datentyp BOOLEAN
Dieser Datentyp ist auf der einen Seite sicherlich recht einfach, doch kann das Arbeiten mit diesem Datentyp mitunter recht spannend werden. Der Datentyp Boolean kennt nur zwei Ausprägungen, wahr (TRUE oder true) oder falsch (FALSE oder false). Es handelt sich um eine zweiwertige Logik, die keine Abstufungen kennt. In der modernen IT gibt es mittlerweile nicht nur zweiwertige Logiken. Denken Sie an die Fuzzy-Logik. Der logische Datentyp wird hauptsächlich bei Vergleichen benötigt, also bei Bedingungen und Schleifen. Da eine Variable verschiedene Datentypen haben kann, gibt es Regeln für die Umwandlung nicht-boolescher Werte wie Zahlen in einen booleschen Wert. Datentyp
Logische Umwandlung
Integer/Float
0 ist false, jeder andere Wert ist true.
String
„“ oder „0“ ist false, jede andere Zeichenkette ist true.
NULL
Immer false.
Tabelle 3.7 Umwandlungstabelle nach Bool
117
Sandini Bib 3 Variablen und ihre Datentypen
Tabelle 3.7 (Forts) Umwandlungstabelle nach Bool
Datentyp
Logische Umwandlung
Array
Kein Eintrag ist false, sonst true.
Objekt
Keine Membervariable gesetzt ist false, sonst true.
Ressourcen
Gültige Ressourcen (z.B. eine offene Datenbankverbindung) sind true, alles andere ist false.
In Tabelle 3.7 sehen Sie die möglichen Umwandlungen anderer Datentypen in die Werte true oder false. In Listing 3.22 sehen Sie diese Umwandlung an einem Beispiel demonstriert. Die Variable $zahlenwert bekommt den Wert 10 zugewiesen. In der darauf folgenden logischen Abfrage wird auf ein logisches true oder false getestet. Die Regel besagt, dass alle Integerwerte außer der 0 einem true entsprechen. Somit muss der echo-Befehl ausgeführt werden. Listing 3.22 Integerwert als logischer Datentyp
Ähnliches können Sie mit einer Zeichenkette durchführen. In Listing 3.23 wird eine Zeichenkette mit dem Wert „0“ deklariert. Nach der Tabelle 3.7 werden leere Zeichenketten „""“ und die Zeichenkette „0“ als false interpretiert. Listing 3.23 Zeichenkette als logischer Wert
Wenn Sie dieses Programm ausführen, werden diese Vermutungen bestätigt. Auf dem Bildschirm erscheint ein: 0 ist false
118
Sandini Bib Der logische Datentyp BOOLEAN
Eine Besonderheit bei logischen Ausdrücken sind die Fließkommazahlen. In fast allen Programmiersprachen, auch in PHP, werden diese Zahlen durch Näherungen dargestellt, da ein Computer mit solchen Zahlen eigentlich nichts anfangen kann. Sein Metier sind die ganzen Zahlen. Bedingt durch diese Näherungen kann es neben anderen Effekten auch zu Ungereimtheiten bei logischen Ausdrücken kommen. Sehen Sie sich als Beispiel das Listing 3.24 einmal genauer an.
Die Konstante M_PI haben wir weiter oben schon kennen gelernt. In PHP gibt es eine mathematische Funktion, welche die Wurzelberechnung einer Zahl durchführt, sqrt(). Wenn man eine Zahl mit sich selber multipliziert und anschließend die Quadratwurzel aus diesem Ergebnis zieht, so erhält man den ursprünglichen Wert. Wenn man zwei identische Zahlen miteinander multipliziert, so spricht man vom Quadrieren dieser Zahlen. So ist das Quadrat von 2 identisch mit der Berechnung 2 * 2, also 4.
Wurzelberechnung, eine kleine Auffrischung
Die Umkehrung dieses Verfahrens entspricht der Frage, welche Zahl man mit sich selbst multiplizieren muss, um das vorliegende Ergebnis zu erhalten, also beispielsweise: Welche Zahl ergibt quadriert die Zahl 4? Für diese Fragestellung ist die Quadratwurzel-Funktion (SquareRoot, sqrt) zuständig. Die Variable $wert sollte also den Wert 0 enthalten. Da der Wert 0 als false interpretiert wird, sollte das Ergebnis lauten: „PI – PI = 0“. Führen Sie das Programm aus, erhalten Sie als Ergebnis des Programms die Zeile: PI - PI ist ungleich 0
119
Sandini Bib 3 Variablen und ihre Datentypen
Mathematisch, logisch haben Sie zwar alles richtig bedacht, aber in der Programmierung befinden Sie sich in den Untiefen des realen Computerdaseins. Wenn Sie das Programm um die Zeile echo "\nwert = $wert.";
erweitern, erhalten Sie als zusätzliche Ausgabe den Wert der Variablen $wert: wert = 4.4408920985006E-016
Dies ist zwar ein Wert sehr nahe bei 0, (0.00000000000000044408...), aber eben nicht genau 0! Und damit schlägt der logische Vergleich quer.
3.10 Logische Operatoren Streng genommen gibt es in PHP nur sechs logische Operatoren, die in Tabelle 3.8 aufgeführt sind. Wie Sie an der Tabelle sehen können, gibt es für die logischen Operatoren „und“ und „oder“ jeweils zwei Operatoren. Welchen der Operatoren Sie benutzen, bleibt Ihnen überlassen. Beide Varianten wurden eingeführt, um den Umstieg aus verschiedenen Programmiersprachen zu erleichtern. So stammen zum Beispiel die Operatoren && und || aus der Programmiersprache C. Allgemein werden die logischen Operatoren nach dem Schema Ausdruck Operator Ausdruck
geschrieben. Im Zusammenhang mit Operatoren spricht man bei den beteiligten Ausdrücken auch von Operanden, so dass auch gilt: Operand Operator Operand.
Der „Nicht“-Operator hat nur einen Operanden, der rechts neben dem Operator aufgeführt werden muss. Tabelle 3.8 Logische Operatoren
120
Operator Name
Ergebnis
and
Und
Wahr, wenn die Ausdrücke links und rechts vom Operator wahr sind
&&
Und
Wahr, wenn die Ausdrücke links und rechts vom Operator wahr sind
or
Oder
Wahr, wenn mindestens einer der Ausdrücke links und rechts vom Operator wahr ist
||
Oder
Wahr, wenn mindestens einer der Ausdrücke links und rechts vom Operator wahr ist
Sandini Bib Logische Operatoren
Tabelle 3.8 (Forts) Logische Operatoren
Operator Name
Ergebnis
!
Nicht
Umkehrung des Ausdrucks rechts vom Operator
xor
Entweder oder Wahr, wenn einer der Ausdrücke links und rechts vom Operator wahr ist, aber nicht beide gleichzeitig
Logische Operatoren werden, mit Ausnahme des „Nicht“-Operators (!), also links und rechts von Ausdrücken umfasst. Zur Erinnerung: Ein Ausdruck kann auch das Ergebnis einer Anweisung sein, zum Beispiel das Ergebnis eines anderen logischen Vergleichs oder das Ergebnis einer Rechenoperation. In den Tabellen 3.9 bis 3.12 finden Sie die Wahrheitstabellen der logischen Operatoren. Sie können diesen Wahrheitstabellen entnehmen, zu welchem Ergebnis eine logische Operation kommt, wenn entsprechende Ausdrücke miteinander kombiniert werden. Linker Ausdruck
Rechter Ausdruck
Ergebnis
Wahr
Wahr
Wahr
Wahr
Falsch
Falsch
Falsch
Wahr
Falsch
Falsch
Falsch
Falsch
Tabelle 3.9 Wahrheitstabelle für den logischen „und“-Operator (and)
Die Operatoren haben mit Ausnahme des not-Operators eine so genannte Linksassoziativität. Dabei handelt es sich um die Richtung, mit der die Auswertung des Operators beginnt. Bei der Linksassoziativität wird erst der linke Operand ausgewertet, anschließend der rechte. In PHP gibt es bei der Auswertung logischer Ausdrücke die so genannte Kurzschlussregel. Sie basiert auf der Tatsache, dass beispielsweise bei der „Und“-Verknüpfung ein einziges „Falsch“ ausreicht, den gesamten Ausdruck als „falsch“ zu bewerten, siehe Tabelle 3.9. Wenn also der linke Ausdruck (Operand) bereits ein „Falsch“ liefert, muss der rechte Operand erst gar nicht ausgewertet werden. Er verändert das Ergebnis auf keinen Fall mehr. PHP bricht an dieser Stelle ab und wertet den rechten Ausdruck nicht mehr aus. Wenn Sie also wissen, dass ein Ausdruck in vielen Fällen „falsch“ ergeben wird, sollten Sie diesen Ausdruck auf die linke Seite des „Und“-Operators bringen. Es spart Ihnen Rechenzeit beim Ablauf des Programms.
121
Sandini Bib 3 Variablen und ihre Datentypen
Vor der Verknüpfung mit den logischen Operatoren werden die beteiligten Operanden erst einmal so weit ausgewertet, dass sie einen logischen Wert ergeben. Diese logischen Werte sind in PHP true und false. Listing 3.25 Skript zur Anwendung des „Und“-Operators ( „and“/„&&“ )
Im Listing 3.25 sehen Sie die Anwendung des „Und“-Operators sowohl auf logische Ausdrücke als auch auf nummerische Ausdrücke. Die Ausgabe des Programms finden Sie in Listing 3.26. Die logische Verknüpfung verhält sich exakt so, wie die Wahrheitstabelle es vermuten lässt. Im zweiten Beispiel des Listings werden zwei Integerwerte miteinander verknüpft. Wie Sie schon wissen, ist die 0 identisch mit dem PHP-Wert false. Der Integerwert 1 steht für true. Sie haben es hier also auch mit der Verknüpfung logischer Werte zu tun. Im dritten Beispiel werden zwei Fließkommazahlen logisch miteinander verknüpft. Bei solchen Operationen gilt immer: Was nicht 0 ist, ist true! Folglich werden zwei wahre Werte miteinander verknüpft, was wiederum einen wahren Wert ergibt.
122
Sandini Bib Logische Operatoren
Wenn Sie das Ergebnis der Verknüpfung wieder in eine Zahl umwandeln, hier in eine Integerzahl, bekommen Sie den Wert 1 – logisch wahr. bool(false) bool(false) bool(true) int(1)
Listing 3.26 Ergebnis von Listing 3.25
Linker Ausdruck
Rechter Ausdruck
Ergebnis
Wahr
Wahr
Wahr
Wahr
Falsch
Wahr
Falsch
Wahr
Wahr
Falsch
Falsch
Falsch
Tabelle 3.10 Wahrheitstabelle für den logischen „Oder“-Operator (or)
Die gleiche Art Kurzschluss existiert bei der „Oder“-Verknüpfung. Da es ausreicht, dass ein Operand „wahr“ ist, um den gesamten Ausdruck „wahr“ werden zu lassen, sollten Sie den Operanden auf die linke Seite setzen, der in den meisten Fällen „wahr“ ergibt.
Im Listing 3.27 sehen Sie die Anwendung des „Oder“-Operators auf logische und nummerische Variablen. Das Ergebnis dieses Skripts ist in Listing 3.28 abgedruckt. Mit den Wahrheitstabellen und dem bisher über nummerische Werte bekanntes Wissen dürften das Skript und die Ergebnisse keine Überraschung mehr bieten. bool(true) bool(true)
Listing 3.28 Ergebnis aus Listing 3.27
123
Sandini Bib 3 Variablen und ihre Datentypen
Tabelle 3.11 Wahrheitstabelle für den logischen Exklusiv-Oder-Operator (xor)
Linker Ausdruck
Rechter Ausdruck
Ergebnis
Wahr
Wahr
Falsch
Wahr
Falsch
Wahr
Falsch
Wahr
Wahr
Falsch
Falsch
Falsch
Der xor-Operator (Entweder – oder) liefert im Gegensatz zum or-Operator nur dann true zurück, wenn nur einer der Operanden true ist. In Listing 3.29 sehen Sie ein Testskript für diesen Operator. Zum Zeitpunkt, wo dieses Skript geschrieben wird, scheint es noch ein Problem mit diesem Operator in PHP 5.0.0 zu geben. Schauen Sie sich die Wahrheitstabelle, das Listing 3.29 und das Ergebnis in Listing 3.30 an! Listing 3.29 Anwendung des Exklusiv-OderOperators (xor)
Das erste Ergebnis sollte eigentlich true ergeben. Leider ist auch das dritte Ergebnis nicht stimmig mit der Wahrheitstabelle. Das Ergebnis sollte false sein! Listing 3.30 Ergebnis aus Listing 3.29
bool(false) bool(true) bool(true) bool(false)
Bevor Sie diesen Operator einsetzen, sollten Sie testen, ob in einer neueren Version dieser Fehler behoben ist!
124
Sandini Bib Vergleichsoperatoren
Rechter Ausdruck
Ergebnis
Wahr
Falsch
Falsch
Wahr
Tabelle 3.12 Wahrheitstabelle für den logischen „Nicht“-Operator (not)
Der „Nicht“-Operator ist recht einfach gestrickt. Er kehrt den logischen Ausdruck, der rechts von ihm steht, ins Gegenteil um. Aus true wird false und umgekehrt. Dass Sie diesen Operator auch auf Zahlen anwenden können, wird in Listing 3.31 gezeigt. bool(false) bool(false)
Listing 3.32 Ergebnis aus Listing 3.32
3.11 Vergleichsoperatoren Die Vergleichsoperatoren gehören zwar nicht zu den logischen Operatoren, da sie aber ebenfalls etwas mit logischen Werten zu tun haben, passt die Besprechung der Vergleichsoperatoren an dieser Stelle gut ins Konzept. Wie der Name schon sagt, werden Vergleichsoperatoren dazu genutzt, Ausdrücke zu vergleichen. Dies wird wichtig, wenn wir uns mit dem Programmablauf beschäftigen. Operator Name
Ergebnis
>
Größer
Wahr, wenn der linke Ausdruck größer als der rechte Ausdruck ist.
>=
Größer oder gleich Wahr, wenn der linke Ausdruck größer als oder gleich dem rechten Ausdruck ist.
Tabelle 3.13 Vergleichsoperatoren in PHP
125
Sandini Bib 3 Variablen und ihre Datentypen
Tabelle 3.13 (Forts) Vergleichsoperatoren in PHP
Operator Name
Ergebnis
=
Beim Vergleich auf „größer“ oder „größer gleich“ analysiert PHP den linken und den rechten Ausdruck und versucht herauszubekommen, welcher Wert der geforderten Bedingung entspricht. Bei ganzen Zahlen (Integer) ist dies sicherlich einfach festzustellen. Problematisch kann es aber bei Fließkommazahlen werden. Wir kommen darauf noch zurück. Was passiert aber, wenn zwei unterschiedliche Datentypen miteinander verglichen werden sollen? Hier versucht PHP wieder, Ihren Wunsch zu erraten. Schauen Sie sich das Listing 3.33 an. Es werden zwei Variablen deklariert, die jeweils einen Zahlenwert beinhalten. Die dritte Variable ist eine Zeichenkette. Aber diese Zeichenkette entspricht einer Zahl. Listing 3.33 Beispielskript für die Operatoren > und >= mit Zahlen
Im ersten Vergleich wird getestet, ob 98.76 größer als 54.32 ist. Dies ist im dezimalen System sicherlich wahr (true). Der zweite Vergleich ist die genaue Umkehrung des ersten Vergleichs. Das Ergebnis muss also false lauten. Der dritte Vergleich scheint zwei unvereinbare Datentypen zu vergleichen. Bei der Besprechung des Datentyps Boolean hatten wir schon einen ähnlichen Fall. PHP sieht auf der linken Seite einen nummerischen Datentyp und auf der rechten Seite eine Zeichenkette, die aber einen nummerischen Ausdruck enthält. Also wird dieser in den entsprechenden nummerischen Datentyp umgewandelt, und der Vergleich kann stattfinden. Da in diesem Beispiel die beiden Zahlenwerte übereinstimmen, ist das Ergebnis des Vergleichs true (siehe Listing 3.34). bool(true) bool(false) bool(true)
Listing 3.34 Ergebnis von Listing 3.33
Sie können diesen Vergleich auch mit Zeichenketten durchführen. In Listing 3.35 werden die Zeichenketten „Alpha“ und „Beta“ miteinander verglichen. Wenn Sie sich das Ergebnis in Listing 3.36 ansehen, schlägt der Vergleich fehl. „Alpha“ ist nicht größer als „Beta“. PHP führt hier einen so genannten lexikalischen Vergleich durch. Und da der Buchstabe „A“ vor dem „B“ im Alphabet steht, ist das Ergebnis des Vergleichs false. Sollte der erste Buchstabe gleich sein, wird der zweite Buchstabe zum Vergleich hinzugezogen usw. Bei diesem Vergleich wird zwischen Groß- und Kleinschreibung unterschieden! „Alpha“ ist also nicht „alpha“. Eine Funktion mit ähnlichem Verhalten werden Sie bei der Besprechung der Zeichenketten kennen lernen: strcmp().
127
Sandini Bib 3 Variablen und ihre Datentypen
Listing 3.35 Beispielskript für den Operator > mit Zeichenketten
Interessant wird das Verhalten, wenn wirklich vollkommen unterschiedliche Datentypen miteinander verglichen werden. Schauen Sie sich den zweiten Vergleich im Listing einmal an. Es wird die Zahl 66 mit der Zeichenkette „Computer“ verglichen. Und wenn Sie auf das Ergebnis in Listing 3.36 schauen, soll 66 auch größer als „Computer sein“, während –5 nicht größer als „Computer“ ist. Listing 3.36 Ergebnis des Skripts aus Listing 3.35
bool(false) bool(true) bool(false)
Wenn Sie sich die booleschen Werte der einzelnen Werte anschauen, so liefern alle drei (66, –5 und „Computer“) den Wert true. Im ersten Fall haben Sie also den Fall true > true ergibt true, im anderen true > true ergibt false! Achten Sie bei Vergleichen auf die Datentypen, die Sie vergleichen! Solche Nebeneffekte können zu sehr schwer auffindbaren Fehlern in Ihren Skripten führen.
3.11.2
Die Operatoren < und
„kleiner“ ist also ein ausschließender, „kleiner gleich“ ein einschließender Vergleichsoperator. Listing 3.40 Ergebnisse aus Listing 3.39
bool(false) bool(true)
3.11.3
Die Operatoren = = und = = =
In PHP taucht das Zeichen „=“ in drei verschiedenen Varianten auf: Als Zuweisung (=) Als Vergleichsoperator auf Gleichheit (= =) Als Vergleichsoperator auf Identität (= = =) Der Unterschied zwischen Gleichheit und Identität liegt an der freien Verwaltung der Typen durch PHP. Wie Sie in den Beispielen schon gesehen haben, werden mitunter Zahlen und die entsprechenden Zeichenketten so verarbeitet, als ob kein Unterschied zwischen ihnen besteht. Wenn Sie einen Blick auf Listing 3.41 werfen, haben Sie im ersten Vergleich einen solchen Fall vorliegen. Die Zahl 15 wird mit der Zeichenkette „15“ verglichen. Ein Blick auf das Ergebnis in Listing 3.42 zeigt, dass PHP Zahl und Zeichenkette als gleich ansieht. Hier schlägt wieder der Interpreter zu. PHP meint, dass Sie Zahlen vergleichen wollen, und wandelt die Zeichenkette in den entsprechenden Datentyp um. Der Vergleich reiner Zahlen wird im zweiten Beispiel des Listings durchgeführt. Da die Zahl 15 nicht der Zahl 14 entspricht, muss das Ergebnis dieses Vergleichs false lauten. Allerdings ist PHP bei dieser Art von Vergleich sehr sorgfältig. Wenn Sie sich das dritte Beispiel anschauen, wird die Zahl 14 mit der Zahl 13.9999999999999999 verglichen. Im normalen Leben würde man sagen, dass diese beiden Zahlen gleich sind. Für PHP sind diese beiden Zahlen aber alles andere als gleich!
130
Sandini Bib Vergleichsoperatoren
Den Unterschied zwischen Gleichheit und Identität erkennen Sie am letzten Beispiel. Auch dort wird wieder die Zahl 15 mit der Zeichenkette „15“ verglichen, diesmal aber mit dem Identitätsoperator. Dieser vergleicht nicht nur die Werte von Variablen, sondern auch den jeweiligen Datentyp. Da der Datentyp Integer der Zahl 15 nicht mit dem Datentyp String der Zeichenkette „15“ übereinstimmt, ist das Ergebnis des Vergleichs false. bool(true) bool(false) bool(false) bool(false) bool(false)
Listing 3.42 Ergebnisse zu Listing 3.41
Der Identitätsoperator vergleicht aber nicht nur allgemein auf Zahlen und Zeichenketten, sondern auf den genauen Datentyp. Dies erkennen Sie am letzten Beispiel aus dem Listing. Dort wird die Integerzahl 15 mit der Fließkommazahl 15.0 verglichen. Da es sich um unterschiedliche Datentypen handelt, liefert dieser Vergleich ebenfalls false! Und die
131
Sandini Bib 3 Variablen und ihre Datentypen
ungewollte Umwandlung von Integer in Float kann im Verlaufe einer Berechnung recht schnell geschehen. Aber auch dafür gibt es eine einfache Lösung. Wir kommen darauf zurück.
3.11.4
Die Operatoren != und != =
Bei den Operatoren „nicht gleich“ und „nicht identisch“ handelt es sich, ähnlich wie bei den Operatoren < und >, um die logische Umkehr. Wenn etwas nicht gleich ist, ist es ungleich. Wenn etwas nicht identisch ist, ist es unterscheidbar (ich wollte hier keine Tautologie benutzen, aber so ganz passend ist der Begriff nicht). In Listing 3.43 finden Sie einige Variablen aus Listing 3.41 wieder. Im ersten Vergleich wird die Zahl 15 mit der Zeichenkette „15“ verglichen, diesmal auf Ungleichheit. Da beim einfachen Vergleich der Datentyp keine Rolle spielt, sind die beiden Variablen gleich, die Anwendung des Operators muss somit false ergeben. Listing 3.43 Beispielskript für die Operatoren != und !==
Die beiden weiteren Vergleiche lassen sich analog herleiten. Listing 3.44 Ergebnisse zu Listing 3.43
bool(false) bool(true) bool(true)
Sie können den Begriff „nicht gleich“ auch direkt in eine Befehlszeile umwandeln. Aus „nicht gleich“ machen Sie „nicht (gleich)“. In die Klammern können Sie nun mit dem Gleichheitsoperator arbeiten, also beispielsweise
132
Sandini Bib Der Datentyp Integer
$value1 != $value2
wird zu ! ( $value1 == $value2 )
Der Klammer-Operator () wurde zwar noch nicht erwähnt, aber seine Funktion dürfte prinzipiell bekannt sein.
3.12 Der Datentyp Integer Bei dem Datentyp Integer handelt es sich um ganze Zahlen, also Zahlen, die keine Nachkommastellen haben. In der Mathematik spricht man auch von den natürlichen Zahlen. Der Zahlenbereich, den man mit diesem Datentyp abdecken kann, liegt zwischen –2.147.483.647 und +2.147.483.647. Diese krummen Zahlen (warum nicht die glatte Zahl 2.000.000.000?) leiten sich aus der Darstellung der Zahlen im Computer ab. Wenn Sie Integerzahlen mit 32 Bit darstellen, also den Bits 0 bis 31, so ist die größte damit darstellbare Zahl der Wert 231 – 1. Die kleinste so darstellbare Zahl ist –(231 – 1). Dies entspricht genau den genannten krummen Werten. Der Wert von knapp 2,1 Milliarden ist zwar recht groß, aber je nach Anwendung kann dies schon zu klein für eine Darstellung sein. So ist die Anzahl der Menschen auf der Erde sicherlich ein Integerwert, aber deutlich über 2 Milliarden. Nun kann es passieren, dass Sie mit Integerwerten rechnen wollen, diesen Bereich aber unbeabsichtigt überschreiten. In PHP führt dies nicht zu einer Fehlermeldung, wie dies in C beispielsweise der Fall wäre. PHP führt automatisch einen Typenwechsel durch. In Listing 3.45 wird dieses Verhalten von PHP provoziert.
Es wird die Variable $max_int mit dem für Integerwerte maximal zulässigen Wert deklariert und anschließend der Datentyp mit der Funktion gettype() ermittelt und ausgegeben. Die Variable $max_int wird um 1 erhöht. Diese Zahl passt nicht mehr in den Integerwertebereich. Wenn Sie sich die Ausgabe des Programms in Listing 3.46 ansehen, stellen Sie fest, dass das Programm anscheinend keine Probleme mit dieser Grenze hat. Es wird die Zahl 2.147.483.648 dargestellt. Die nächste Zeile sagt Ihnen, was PHP intern vollzogen hat, einen Typenwechsel. Die Variable ist jetzt eine Fließkomma-Variable. Bei der nächsten Berechnung wird von diesem Wert 100 abgezogen. Damit befindet sich die Variable wieder eindeutig im Bereich der Integerwerte. Dies kann man bei der Ausgabe auch deutlich am ausgegebenen Wert sehen. Aber Achtung: Die Variable wird jetzt nicht automatisch in eine Integer-Variable umgesetzt. Es bleibt eine Fließkomma-Variable. Listing 3.46 Ausgabe von Listing 3.45
Datentyp ist integer 2147483648 Datentyp ist jetzt double 2147483548 Datentyp ist jetzt double
Wenn Sie jetzt mit dieser Variablen in logische Ausdrücke gehen, kann Ihnen das weiter oben geschilderte Problem begegnen. Wenn Sie wissen, dass Ihnen dies bei der Berechnung passieren kann, können Sie den Typ der Variablen zwangsweise setzen. Hierfür kann man wie in C mit einem so genannten Cast arbeiten. In Listing 3.47 sehen Sie zwei Beispiele für die vom Programmierer erzwungene Typenumwandlung. Listing 3.47 Typumformung nach Integer mittels Casting
Der Datentyp der Variablen $var_val mit dem Wert 5.9 wird mit dem Cast (int) zwangsweise nach Integer konvertiert. Dabei werden alle Nachkommastellen abgeschnitten. Als Ergebnis erhalten Sie eine Integervariable mit dem Wert 5. Der Wert Datentyp Der Wert Datentyp
ist ist ist ist
jetzt: 5 jetzt integer jetzt: 144 jetzt integer
Listing 3.48 Ausgabe des Programms von Listing 3.47
Interessanter ist die zweite Typenumwandlung. Die Zeichenkette „144 Tassen Kaffee“ soll in einen Integerwert umgewandelt werden. Wenn Sie auf die beiden letzten Zeilen in Listing 3.48 achten, gelingt dies auch ohne Fehler. PHP nimmt sich aus der Zeichenkette die Zeichenkette „144“ und schneidet den Rest ab. Dieser Teil kann problemlos in einen Integerwert gewandelt werden. Dies gelingt PHP aber nur dann, wenn etwas am Anfang einer Zeichenkette steht, die in eine Zahl umgewandelt werden kann. Wenn Sie die Zeile in $var_val = "Nur 144 Tassen Kaffee";
ändern, erhalten Sie zwar auch keine Fehlermeldung, aber der Wert entspricht wahrscheinlich auch nicht der gewünschten Form: Der Wert ist jetzt: 0 Datentyp ist jetzt integer
Da PHP keine Zahl am Beginn der Zeichenkette findet, wird für den Cast eine leere Zeichenkette genommen – und diese wird in die Zahl 0 mit dem Datentyp Integer transformiert. Bisher haben wir für Integerwerte immer das dezimale Zahlensystem verwandt. In der Datenverarbeitung gibt es aber daneben noch das hexadezimale (auf der Basis 16 basierend) und das oktale (auf der Basis 8 basierend) Zahlensystem.
135
Sandini Bib 3 Variablen und ihre Datentypen
Tabelle 3.14 Präfixe für Integerzahlen anderer Zahlensysteme
Zahlensystem
PHP Integer-Präfix
Dezimal
Kein
Oktal
0
Hexadezimal
0x
In Tabelle 3.14 finden Sie die Präfixe, die Sie für Zahlen in den anderen Zahlensystemen verwenden müssen. Wie zu erwarten war, benötigt man für unser normales dezimales System kein Präfix. In Listing 3.49 finden Sie jeweils ein Beispiel für die Zahl 10 in den verschiedenen Systemen. Listing 3.49 Darstellung der Zahl 10 in den drei Zahlensystemen
Wenn Sie dieses Programm ausführen, erhalten Sie die in Listing 3.50 gezeigte Ausgabe. Wie man sieht, erfolgt die Ausgabe einer Zahl immer im dezimalen System, egal welches System für die Eingabe einer Zahl benutzt wurde. Listing 3.50 Ausgabe des Programms aus Listing 3.49
10 16 8
Wenn Sie „normale“ Anwendungsprogramme schreiben, könnte die erste Reaktion sein: „Eigentlich brauche ich ja keine anderen Zahlensysteme.“ Die zweite: „Mmh, was ist mit führenden Nullen bei der Eingabe durch einen Benutzer?“. Hier hilft die Typenumwandlung von Zeichenketten. Wenn eine Zeichenkette in einen Integerwert umgewandelt
136
Sandini Bib Der Datentyp Integer
wird, wird eine führende Null nicht als Indiz für eine oktale Zahl angesehen. Die Umwandlung geschieht in das dezimale System. Und da Benutzereingaben erst einmal als Zeichenkette im Programm zur Verfügung stehen, gibt es keine Probleme bei führenden Nullen in der Benutzereingabe. Das unterschiedliche Verhalten wird durch Listing 3.51 noch einmal verdeutlicht. Im ersten Teil wird der Variablen $int_val der Integerwert 0567 übergeben. Durch die führende Null wird die Zahl als Oktalzahl interpretiert und entsprechend in das dezimale System umgerechnet. Intern arbeitet PHP mit dem C-Datentyp long, und dieser speichert dezimale Werte.
Zu dieser nun umgerechneten Zahl wird 2 addiert, und das Ergebnis lautet (0567 = 375): Integerwert aus Oktal ist 377
Im zweiten Teil wird der String-Variablen $string_var die Zeichenkette „0567“ übergeben. Bei der Umwandlung in eine Zahl werden die führenden Nullen abgeschnitten und die „Restzahl“ in den Datentyp Integer umgewandelt. Da dies zur Zahl 567 führt, lautet das Ergebnis der Addition: Integerwert aus String ist 569
Wenn Sie sich den Datentyp und den Wert einer Variablen ansehen wollen, können Sie die Funktion var_dump() einsetzen. Wenn Sie dieser Funktion eine Variable übergeben, werden Datentyp und Wert dieser Variablen zurückgeliefert. Wenn Sie das Programm aus Listing 3.51 auf diese Funktion umstellen, erhalten Sie das Programm aus Listing 3.52.
137
Sandini Bib 3 Variablen und ihre Datentypen
Listing 3.52 Anwendung der Funktion var_dump()
Wenn Sie dieses Programm ausführen, erhalten Sie die Ausgabe von Listing 3.53. Wie Sie erkennen, werden bei Integer-Variablen der Datentyp und der Wert in Klammern angezeigt. Bei Zeichenketten wird zusätzlich die Länge der Zeichenkette mit ausgegeben. Listing 3.53 Ausgabe des Programms aus Listing 3.52
int_val ist: int(375) int_val ist: int(377) string_val ist: string(4) "0567" string_val ist: int(569)
3.13 Der Datentyp Fließkomma Nicht immer kommt man mit Integerwerten aus. Sei es, weil der Wertebereich nicht ausreicht oder weil in der Berechnung Nachkommastellen benötigt werden. In diesem Fall kommen die Fließkomma-Zahlen zum Einsatz. Wie im letzten Abschnitt schon erwähnt, haben diese Zahlen keine unendliche Genauigkeit. Da Sie fast beliebige Zahlen in einem begrenzten Speicherbereich ablegen müssen (C-Datentyp double), kann es zu Rundungsfehlern kommen. Die Genauigkeit der Darstellung beträgt typischerweise 14 signifikante Stellen. Zur Verdeutlichung dient Listing 3.54. Sie können eine Zahl mit Nachkommastellen „normal“ eingeben. Hierbei müssen Sie allerdings darauf achten, dass im deutschen Sprachraum ein Komma den Vorkomma- und Nachkommabereich trennt (daher ja auch der Name), im amerikanischen und internationalen Sprachraum aber der Punkt. Sie müssen Fließkommazahlen also als Fließpunkt-(Floating-Point-)Zahlen schreiben. Die Zahl 342,987 wird also als 342.987 geschrieben.
138
Sandini Bib Der Datentyp Fließkomma
Es gibt aber noch eine weitere Schreibweise für Fließkommazahlen. Wenn Sie sich an den Mathematikunterricht zurückerinnern, kann man eine Zahl auch in der so genannten Exponentialdarstellung schreiben. Aus der Zahl 342,987 wird so 3,42987 * 102. Bildlich gesprochen verschieben Sie das Komma um zwei Stellen nach links und fügen am Ende der Zahl die entsprechende Zehnerpotenz hinzu. Diese Zahl können Sie in PHP direkt so eingeben. Statt der 102 schreiben Sie aber e2 an das Ende der Zahl. Wenn Sie das Komma in diesem Beispiel um drei Stellen nach links schieben, erhalten Sie die Zahl 0,342987 * 103. In PHP können Sie diese Zahl als 0.342987e3 oder, noch kürzer, als .342987e3 schreiben, indem Sie die führende Null streichen (wobei Sie aber auf keinen Fall den Punkt weglassen dürfen …). Sie können jede Zahl in dieses letzte gezeigte Format bringen. 14 signifikante Stellen heißt nun, dass zwischen dem Punkt und dem e 14 Ziffern für die Berechnung relevant sind. Stehen mehr Ziffern nach einer Berechnung zur Verfügung, so haben diese Ziffern keinerlei Relevanz für die Berechnung. Sie täuschen eine falsche Genauigkeit vor. Abgespeichert werden Variablen vom Typ Fließkomma nach dem IEEE64-BIT-Verfahren. Damit können Sie Zahlen darstellen, die einen Wert von rund 1,8 * 10308 erreichen! Die Ausgabe des Programms aus Listing 3.54 ist übrigens float(342.987) float(342.987) float(342.987)
Listing 3.55 Ausgabe des Programms aus Listing 3.54
Wie bei den Zahlen vom Datentyp Integer können Sie auch beim Datentyp Fließkomma eine Variable zum Typwechsel zwingen. In Listing 3.56 sehen Sie hierfür ein Beispiel.
139
Sandini Bib 3 Variablen und ihre Datentypen
Listing 3.56 Type-Cast auf Fließkomma
Zuerst wird eine Variable angelegt, die aufgrund der Zahl dem Datentyp Integer zugeordnet wird. Durch den Cast-Operator (double) wird PHP gezwungen, den Datentyp dieser Variablen zu ändern. Das dies wunschgemäß funktioniert, können Sie der Ausgabe der Funktion var_dump() entnehmen. Sie liefert: Listing 3.57 Ausgabe des Programms aus Listing 3.56
int(3) float(3)
Neben dem (double)-Cast existieren noch (real) und (float). Alle drei Cast-Operatoren führen zum Ergebnis aus Listing 3.57.
3.14 Mathematische Operationen Mit der Mathematik begeben wir uns zu den Ursprüngen der Computertechnologie. Aber auch hier hat sich das eine oder andere im Laufe der Jahrzehnte getan. Selbst wenn PHP nicht zu den Sprachen gehört, die einem spontan einfallen, wenn es um komplizierte und ausgedehnte Berechnungen geht, so können Sie mit PHP mittlerweile genauso gut rechnen als mit den dafür speziell geschaffenen Sprachen. Mit der Geschwindigkeit geht’s nicht so flott von der Hand. Aber selbst bei der Berechnung von Planetenbahnen muss PHP den Vergleich nicht scheuen. In Tabelle 3.15 sehen Sie die in PHP zur Verfügung stehenden mathematischen Operatoren. Es gibt Programmiersprachen, die nicht diesen Umfang an Operatoren erreichen. Tabelle 3.15 Mathematische Operationen nach Rang
140
Operator Name
Ergebnis
+
Unäres Plus
Weist dem rechts stehenden Ausdruck das positive Vorzeichen zu.
-
Unäres Minus
Weist dem rechts stehenden Ausdruck das negative Vorzeichen zu.
Sandini Bib Mathematische Operationen
Operator Name
Ergebnis
++
Post-Inkrement
Nach der weiteren Verarbeitung wird der Ausdruck um 1 erhöht.
--
Post-Dekrement Nach der weiteren Verarbeitung wird der Ausdruck um 1 vermindert.
++
Prä-Inkrement
Vor der weiteren Verarbeitung wird der Ausdruck um 1 erhöht.
--
Prä-Dekrement
Vor der weiteren Verarbeitung wird der Ausdruck um 1 vermindert.
*
Multiplikation
Der links stehende Ausdruck wird mit dem rechts stehenden Ausdruck multipliziert.
/
Division
Der links stehende Ausdruck wird mit dem rechts stehenden Ausdruck dividiert.
%
Rest-Division
Der links stehende Ausdruck wird mit dem rechts stehenden Ausdruck modulo-dividiert (Resteberechnung).
+
Addition
Der links stehende Ausdruck wird mit dem rechts stehenden Ausdruck addiert.
-
Subtraktion
Der links stehende Ausdruck wird mit dem rechts stehenden Ausdruck subtrahiert.
Tabelle 3.15 (Forts) Mathematische Operationen nach Rang
Mathematische Operationen wie etwa die Berechnung der Quadratwurzel oder des Sinus finden sich nicht an dieser Stelle. Dabei handelt es sich um eine vollkommen andere Art von Operationen, die in PHP, wie auch beispielsweise in C/C++, in den Bereich der Funktionen ausgelagert wurden.
3.14.1
Unäres Plus/Addition
Der „+“-Operator erscheint in PHP in zwei Ausprägungen, wovon die erste kaum oder gar nicht benutzt wird: das so genannte „unäre Plus“. Es dient dazu, eine Zahl mit einem positiven Vorzeichen zu versehen. Mathematisch entspricht es der Multiplikation mit (+1). Wie Sie sich leicht ausrechnen können, geschieht bei der Multiplikation mit 1 aber nichts, auch das vorhandene Vorzeichen wird nicht geändert. Die zweite Bedeutung des „+“-Operators ist die Addition von Werten. Dabei wird erst der Ausdruck (Operanden) auf der linken Seite ausgewertet und anschließend der Ausdruck der rechten Seite hinzuaddiert. Das Ergebnis der Berechnung wird typischerweise einer Variablen zugewiesen oder, als Bestandteil einer längeren Anweisung, weiter verarbei-
141
Sandini Bib 3 Variablen und ihre Datentypen
tet. Dabei behalten die Operanden ihren Wert bei. Sollte einer der Operanden auf der linken Seite der Zuweisung (=) stehen, so wird dessen Wert geändert und steht nicht mehr zur Verfügung. In Listing 3.58 sehen Sie einige Beispiele zur Nutzung dieses Operators. Die Ergebnisse der einzelnen Berechnungen finden Sie in Listing 3.59. Listing 3.58 Beispiele für den „+“-Operator
Das erste Beispiel soll nochmals verdeutlichen, dass das unäre Plus keine Auswirkung auf die betroffenen Zahlen hat. Der negative Integerwert behält sowohl Datentyp als auch Wert bei. Im zweiten Beispiel werden drei Integerwerte addiert. Da dies von links beginnend geschieht, die Variablen selber aber nicht verändert werden, geht PHP so vor: Der Wert 15 wird an eine gerade freie Stelle im Hauptspeicher abgelegt. Dann wird der Wert 25 zum Wert 15 addiert und an die gleiche Stelle im Hauptspeicher wieder abgelegt. Anschließend wird der Wert 10 aus dem Programm zum Zwischenergebnis (40) addiert und wiederum an der gleichen Stelle des Hauptspeichers abgelegt. Zum Schluss wird der zwischengespeicherte Wert (50) der Variablen auf der linken Seite des Zuweisungsoperators zugeordnet. Der Speicherbereich, der für die Addition benötigt wurde, wird wieder freigegeben.
142
Sandini Bib Mathematische Operationen
Der Platz dieser Variablen befindet sich ebenfalls im Hauptspeicher des Rechners. Bei diesem Rechner handelt es sich übrigens um den Computer, auf dem das PHP-Programm abläuft. Dies ist normalerweise der Server und nicht der PC, auf dem beispielsweise der Browser läuft. Im dritten Beispiel werden eine Integer- und eine Fließkommazahl addiert. Das Ergebnis dürfte nicht überraschen. Für den einen oder anderen dürfte das Ergebnis der vierten Berechnung aber eine kleine Überraschung bringen. Zum Integerwert 15 wird die Fließkommazahl 5.0 addiert. Das Ergebnis wird mit dem echo-Befehl auch als 20 angezeigt, also einem Integerwert. Wie Sie der Ausgabe der Funktion var_dump() aber entnehmen können, handelt es sich bei dem Ergebniswert um eine float-Zahl! Das Ergebnis des unären Plus ist: -5 int(-5)
Listing 3.59 Ergebnisse des Skripts aus Listing 3.58
Das Ergebnis der Integeraddition ist: 50 int(50) Das Ergebnis der gemischten Addition ist: 20.5 float(20.5) Das Ergebnis der gemischten Addition ist: 20 float(20)
Sie können davon ausgehen, dass das Ergebnis einer Addition immer dann den Datentyp float ergibt, wenn eine der beteiligten Variablen vom Datentyp float ist.
3.14.2
Unäres Minus/Subtraktion
Die Subtraktion bietet im Vergleich zur Addition nichts Neues – wenn man davon absieht, dass Zahlen voneinander abgezogen und nicht addiert werden. Interessant ist an dieser Stelle das Verhalten des unären Minus. Das unäre Minus verhält sich wie die Multiplikation mit (–1). Wie Sie vielleicht noch aus der Mathematik wissen, bedeutet dies die Umkehr des Vorzeichens. Aus + wird – und aus – wird +. In Listing 3.60 wird dieses Verhalten getestet.
143
Sandini Bib 3 Variablen und ihre Datentypen
Listing 3.60 Verhalten des unären Minus
In den ersten beiden Beispielen wird der Wechsel des Vorzeichens deutlich. Das unäre Minus kann aber nicht nur in dieser Art benutzt werden. Rechts neben dem unären Minus kann ein kompletter Ausdruck stehen. Im dritten Beispiel wird dies am doch recht einfach gehaltenen Ausdruck 5 + 6 verdeutlicht. Listing 3.61 Ergebnisse aus Listing 3.60
Das Ergebnis des unären Minus von -5 ist: 5 int(5) Das Ergebnis des unären Minus von 5 ist: -5 int(-5) Das Ergebnis von -(5 + 6) ist: -11 int(-11)
An dieser Stelle wird auch die Formulierung „nach Rang“ in der Tabellenunterschrift von Tabelle 3.15 wichtig. Sie bedeutet, dass im Zweifelsfall die Operationen zuerst ausgeführt werden, die weiter oben im Rang stehen. Da das unäre Minus weiter oben steht, wäre ohne Klammern die Berechnung –5 + 6 ausgeführt worden, was nach Adam Riese 1 ergibt. Bei der Subtraktion gilt auch die Regel für die Datentypen: integer gemischt ergibt immer float.
3.14.3
float
und
Multiplikation
Genau wie die Addition und die Subtraktion zählt die Multiplikation zu den vier Grundrechenarten. Der Operator für die Multiplikation ist das „*“-Zeichen, da es einen Multiplikationspunkt wie in der Mathematik nicht gibt.
144
Sandini Bib Mathematische Operationen
Ich werde hier nicht näher darauf eingehen, was Multiplikation eigentlich ist. An eine Regel aus dem Mathematikunterricht möchte ich Sie aber an dieser Stelle erinnern: „Punktrechnung geht vor Strichrechnung.“ In Programmiersprachen wie PHP wird diese Regel durch den höheren Rang (siehe Tabelle 3.15) realisiert. In Listing 3.62 wird dies an einem Beispiel deutlich.
Die erste Berechnung enthält sowohl eine Multiplikation als auch eine Addition. Die Multiplikation zählt neben der Division zur Punktrechnung. Daher werden erst die Zahlen 12 und 34 miteinander multipliziert, und auf dieses Ergebnis wird dann die Zahl 56 addiert. Ist dieses Verhalten nicht gewünscht, können Klammern eingesetzt werden. Diese Klammern dienen dazu, erst die Ausdrücke innerhalb der beiden Klammern zu berechnen. Anschließend wird mit der Berechnung außerhalb der Klammern fortgesetzt. Setzt man die Klammern in unserem Beispiel um die Multiplikation, darf sich das Ergebnis nicht ändern – die Reihenfolge der Berechnung wird durch diese Klammerung ja nicht verändert. Wenn Sie sich die zweite Berechnung in Listing 3.62 ansehen, wird exakt dies durchgeführt. Ein Blick auf die Rechenergebnisse in Listing 3.63 zeigt, dass auch PHP so verfährt. Will man erst die Addition ausführen lassen, muss die Berechnung von 34 + 56 in Klammern gesetzt werden. Dies finden Sie im dritten Beispiel. Wie die Ausgabe zeigt, ist das Ergebnis der Berechnung auch ein anderes.
145
Sandini Bib 3 Variablen und ihre Datentypen
Listing 3.63 Ergebnis aus Listing 3.62
Das Ergebnis von 12 * 34 + 56 ist: 464 Das Ergebnis von ( 12 * 34 ) + 56 ist: 464 Das Ergebnis von 12 * ( 34 + 56 ) ist: 1080
Wie Sie sehen, kann man auch Klammern setzen, wenn diese nicht unbedingt notwendig sind. Bei der Berechnung in unserem Beispiel mag dies sicherlich überflüssig sein. Sie können aber bei komplizierteren Berechnungen beliebig viele, auch ineinander geschachtelte Klammern setzen. Und des Öfteren erleichtert es das Verständnis einer Formel, wenn auch unnötige Klammern gesetzt sind. Auch hier gilt wieder die Regel float vor integer.
3.14.4
Division/Restdivision
Von den vier Grundrechenarten bildet die Division eine kleine Ausnahme, da es zwei Arten von Divisionen gibt. Zum einen die Art von Division, wie sie im täglichen Leben allgemein bekannt ist und angewandt wird. Der Operator hierfür ist in PHP das /-Zeichen. Die andere Art der Division ist die so genannte Restdivision. Es ist eigentlich die einfachere Form der Division, da man ohne Nachkommastellen auskommt. Diese Art der Division wird mit dem %-Operator durchgeführt. In diesem Zusammenhang hat das Zeichen „%“ nichts mit der Prozentrechnung zu tun! Der Unterschied zwischen den beiden Arten wird am besten an ein paar Beispielen klar: Die Division 3 / 2 ergibt mit der üblichen Division 1,5 oder auch 1½. Bei der Restdivision lautet das Ergebnis: 1 Rest 1. Die Division 10 / 5 ergibt genau 2. Die Restdivision ergibt: 2 Rest 0. Ein letztes Beispiel: 9 / 4 ergibt 2,25 oder 2¼. Die Restdivision ergibt 2 Rest 1. Jetzt kann man sich die Frage stellen, wo solche Divisionen im täglichen Leben auftauchen. Erstaunlicherweise rechnet jeder damit, ohne es zu merken. Beispielsweise bei der Rechnung 18 Stunden plus 10 Stunden sind 28 Stunden. Dies sind 1 Tag und 4 Stunden. Die Restdivision mit 24 also. Gleiches gilt bei Gradangaben. Sie fahren mit Ihrem Auto in Richtung 2700. Dann machen Sie einen Schwenk um 1200 nach links. Sie fahren somit in die Richtung 3900. Da ein Kreis nur 3600 hat, können Sie wieder die Restdivision durchführen. In diesem Fall benötigen Sie nur den Rest der Division, 300. Jetzt könnte man dieses Ergebnis auch durch die Subtraktion von 360 erreichen, aber was ist, wenn
146
Sandini Bib Mathematische Operationen
Sie sich mit dem Wagen 2x, 3x, 5x oder 10x um die eigene Achse drehen? Und: Sie benötigen keine Fallunterscheidung nach dem Schema „Wenn der Winkel größer als 360 ist, dann ... sonst ...“. Die Restdivision hat den Vorteil, auch bei Werten zu funktionieren, die kleiner als der Divisor sind: 291 / 360 = 0 Rest 291. Diese Art der Division wird auch „Modulo“-Division genannt. In anderen Programmiersprachen finden Sie für diese Art der Berechnung beispielsweise die Funktion mod(). Man sagt in diesem Zusammenhang auch nicht „3 geteilt durch 2“ oder „3 dividiert durch 2“, sondern „3 modulo 2“. In Listing 3.64 finden Sie das Grundgerüst, mit dem Sie die oben gezeigten Rechenbeispiele in PHP nachvollziehen können. Sie müssen nur die Variablen $a und $b mit anderen Werten besetzen.
Für die Berechnung im Listing 3.64 finden Sie das Ergebnis in Listing 3.65. Das Ergebnis der „normalen“ Division wird in der Variablen $result_div abgespeichert. Wie Sie an der Ausgabe von var_dump() erkennen können, wird dabei das erwartete Ergebnis 1,5 berechnet. Die Modulo-Division liefert uns den Restwert. Um das komplette Ergebnis der Berechnung angeben zu können, benötigen wir den Vorkommawert der ersten Division. Diesen Wert kann man durch den (int) - Cast erreichen. Bei der Umwandlung einer Fließkommazahl in eine Ganzzahl wird nur der Vorkommawert genommen, egal wie groß der Nachkommawert auch ist. Dieser gecastete Wert wird in der Variablen $result_int gespeichert. Damit kann das Ergebnis ausgegeben werden.
147
Sandini Bib 3 Variablen und ihre Datentypen
Listing 3.65 Ergebnis von 3 / 2 und 3 % 2
Direkte Rechenergebnisse: float(1.5) int(1) Die Restdivision von 3 durch 2 ergibt: 1 Rest 1
Um das letzte Beispiel (291 / 360) zu berechnen, müssen Sie im Listing 3.64 die ersten Zeilen durch $a = 291; $b = 360;
ersetzen. Bei der Division erhalten Sie den Fließkommawert 0,8033... Die Modulo-Division liefert Ihnen den Wert 291, und für den Cast gilt (int) 0.80333 ist 0. Listing 3.66 Die Berechnung 291 % 360
Direkte Rechenergebnisse: float(0.80833333333333) int(291) Die Restdivision von 291 durch 360 ergibt: 0 Rest 291
Wie bei der Multiplikation wird die Division vor der Addition und/oder der Subtraktion durchgeführt. Auch hier müssen Sie Klammern setzen, wenn Sie die Reihenfolge der Berechnung verändern wollen. Bleibt zu erwähnen, dass das Ergebnis der Modulo-Division immer ein Integerwert ist. Sollten Sie zudem Fließkommawerte für die ModuloDivision benutzen, werden diese erst in Integerwerte umgewandelt, und anschließend wird die Division durchgeführt: Die Restdivision von 5.6 durch 3.2 ergibt: 1 Rest 2
3.14.5
Inkrement/Dekrement
Bei der Programmierung stößt man recht schnell auf Situationen, in denen beispielsweise einzelne Punkte einer Liste durchlaufen werden müssen oder die Anzahl bestimmter Einträge festgestellt werden soll. Sie müssen dann einen Zähler entweder immer um eins erhöhen oder verringern. Dies lässt sich immer mit der Anweisung $i = $i + 1;
oder $i = $i – 1;
erreichen. In PHP gibt es, wie in C/C++ auch, eine abkürzende Schreibweise, den Inkrement- und den Dekrement-Operator. Während der
148
Sandini Bib Mathematische Operationen
Inkrement-Operator (++) eine Variable um 1 erhöht, verringert der Dekrement-Operator (--) eine Variable um den Wert 1. Dabei wird das Ergebnis automatisch der angegebenen Variablen wieder zugeordnet. Die obigen Zeilen können damit also einfach als $i++;
und $i--;
geschrieben werden. Man spricht hier von Post-Inkrement und PostDekrement, da die Operatoren nach (post) der Variablen stehen. Exakt das gleiche Ergebnis erreichen Sie in diesem Beispiel durch die Zeilen ++$i;
und --$i;
In diesem Fall spricht man von Prä-Inkrement und Prä-Dekrement, da die Operatoren vor (prä) der Variablen stehen. In Listing 3.67 wird die Variable $counter von null beginnend zuerst mit dem Post-Inkrement-Operator und anschließend mit dem Prä-Inkrement-Operator jeweils um 1 erhöht (siehe Listing 3.68). Direkt anschließend wird mit dem Post-Dekrement- und dem Prä-Dekrement-Operator wieder heruntergezählt. Wie Sie bemerken werden, kann man nach einem Prä-Inkrement ein Post-Dekrement folgen lassen. Die andere Reihenfolge ist natürlich auch möglich.
In der letzten Zeile folgt nochmals ein Dekrement-Operator, der die Variable in den negativen Zahlenbereich wachsen lässt (auf –1). Listing 3.68 Ergebnisse aus Listing 3.67
Counter Counter Counter Counter Counter Counter
hat hat hat hat hat hat
den den den den den den
Wert: Wert: Wert: Wert: Wert: Wert:
0 1 2 1 0 -1
In den gezeigten Beispielen erkennt man noch nicht den Unterschied zwischen Prä- und Post-Operator. Schauen Sie sich dazu das Listing 3.69 an. Die Variable $value wird mit dem Wert 100 deklariert. Die Variable $counter wird aus der Variablen $value ermittelt, wobei diese Variable mit dem Post-Inkement-Operator ausgestattet ist. Wenn Sie sich jetzt das Ergebnis dieser Zuweisung in Listing 3.70 anschauen, werden Sie feststellen, dass die Variable $counter den ursprünglichen Wert von $value besitzt. In der nächsten Zeile wird der Variablen $counter nochmals der Wert von $value zugewiesen; diesmal aber ohne irgendeinen Operator, der Einfachheit halber. Jetzt ist der Wert gleich 101. Die Ursache liegt in der Benutzung des Post-Operators. Das „Post“ im Namen bedeutet nicht nur, dass der Operator rechts vom Operanden steht, sondern auch, dass das Hoch- oder Runterzählen um 1 erst nach der Auswertung des Ausdrucks geschieht, in welcher der Post-Operator steht. Listing 3.69 Beispiel für den PostInkrement-Operator
150
Sandini Bib Mathematische Operationen
Im gezeigten Fall bedeutet dies, dass erst der echo-Befehl ausgeführt wird (der Ausdruck) und dann die Variable hochgezählt wird. Damit hat sie bei der nächsten Zuweisung an $counter den um 1 erhöhten Wert. Der Zähler hat den Wert 100 Jetzt hat er den Wert 101
Listing 3.70 Ergebnisse aus Listing 3.69
Analog dazu wird beim Prä-Operator vor der Auswertung des Ausdrucks die entsprechende Variable hoch- oder runtergezählt. Wenn Sie die Zeile mit dem Post-Inkrement-Operator in Listing 3.69 in $counter = ++$value;
ändern, werden Sie die erwartete Ausgabe Der Zähler hat den Wert 101
erhalten. Was wir hier für den Inkrement-Operator erörtert haben, gilt entsprechend auch für den Dekrement-Operator. Sie können dies ebenfalls sehr einfach mit dem Skript aus Listing 3.69 testen. Sie müssen nur das ++ durch ein -- ersetzen. Bei logischen Vergleichen wird der Unterschied sehr deutlich. In Listing 3.71 wird angenommen, dass eine Zählvariable ($counter) irgendwie den Wert 99 erreicht hat. Dargestellt wird dies durch die Zuweisung des Wertes 99 an die Variable. Bei dem Test, ob diese Variable den Wert 100 oder darüber erreicht hat, wird der Post-Inkrement-Operator benutzt. Das Ergebnis dieses Vergleichs wird in der Variablen $val_bool gespeichert.
Der Zähler $counter wird nach dem Vergleich erhöht, ist also zum Zeitpunkt des Vergleichs noch bei 99. Entsprechend ist das Ergebnis wie in Listing 3.72 gezeigt. bool(false)
Listing 3.72 Ergebnis des Vergleichs aus Listing 3.71
151
Sandini Bib 3 Variablen und ihre Datentypen
Setzen Sie an dieser Stelle den Prä-Inkrement-Operator ein $val_bool = ++$counter >= 100;
wird die Variable vor dem Vergleich um 1 erhöht, und der Vergleich ergibt true.
3.15 Zusammengesetzte Operatoren Nun gibt es bei der Programmierung nicht nur die Situation, dass man einen Wert um 1 erhöhen oder verringern möchte, sondern vielleicht um den Wert 2, 4 oder vielleicht sogar 8. In solchen Fällen bliebe einem normalerweise nichts anderes übrig, als eine Anweisung wie $value = $value * 8;
zu schreiben. Da Programmierer von Haus aus schreibfaul sind, gibt es für diese Art der Wertzuweisung ebenfalls eine Abkürzung: $value *= 8;
In Tabelle 3.16 finden Sie eine Aufstellung aller in PHP möglichen zusammengesetzten Operatoren. Tabelle 3.16 Zusammengesetzte Operatoren
Operator
Bedeutung
+=
Der Ausdruck der rechten Seite wird mit der Variablen der linken Seite addiert.
-=
Der Ausdruck der rechten Seite wird mit der Variablen der linken Seite subtrahiert.
*=
Der Ausdruck der rechten Seite wird mit der Variablen der linken Seite multipliziert.
/=
Der Ausdruck der rechten Seite wird mit der Variablen der linken Seite dividiert.
%=
Der Ausdruck der rechten Seite wird mit der Variablen der linken Seite modulo-dividiert.
.=
Die Zeichenkette rechts vom Operator wird an die Zeichenkettenvariable links vom Operator angehängt ( .-Operator; siehe nächstes Kapitel).
In Listing 3.73 finden Sie für alle nummerischen Operatoren je ein Beispiel. Die Ausgabe dieses Skriptes finden Sie in Listing 3.74.
152
Sandini Bib Zusammengesetzte Operatoren
Das Programm beginnt mit der Deklaration der Variablen $value. Diese Variable wird auf den Startwert 100 gesetzt. In der ersten Rechenoperation wird dann der Wert 6 hinzuaddiert (106). Nach der Subtraktion von 16 (90) wird die Variable mit dem Wert 3 multipliziert (270) und anschließend durch 6 dividiert (45). Die nächste Rechenoperation ist die Modulo-Division durch 8. Diese Division ergibt einen Rest von 5. Die letzte Rechenoperation sollten Sie sich nochmals anschauen. Auch hier wird wieder multipliziert, allerdings steht jetzt auf der rechten Seite ein etwas umfangreicherer Ausdruck als eine einfache Zahl. PHP wertet diesen Ausdruck erst aus, bevor die Multiplikation durchgeführt wird. Dieser Rechenschritt entspricht also der Multiplikation mit 4, was den Wert 20 ergibt. Würde der rechte Ausdruck nicht komplett ausgewertet, so hätten Sie erst eine Multiplikation mit 2, gefolgt von der Addition mit 2. Sie hätten dann das Ergebnis 18, was eindeutig nicht der Fall ist. $value $value $value $value $value $value
= = = = = =
106 90 270 45 5 20
Listing 3.74 Ergebnisse aus Listing 3.73
153
Sandini Bib 3 Variablen und ihre Datentypen
Die letzte Anweisung entspricht also der Anweisung $value = $value * ( 2 + 2 );
wenn Sie nicht den zusammengesetzten Multiplikationsoperator benutzen würden!
3.16 Mathematische Funktionen Mit den bisher gezeigten mathematischen Operatoren können Sie jedes Berechnungsproblem lösen, was Ihnen je gestellt werden wird! Allerdings würde es Sie viel Zeit und Mühe kosten, die notwendigen Berechnungen selber zu programmieren, vor allem wenn die Mathematik nicht zu Ihren Leidenschaften zählt. Aus diesem Grund gibt es in PHP einen stattlichen Vorrat an Funktionen, die Ihnen die Arbeit mit Zahlen erheblich erleichtern können. Im Handbuch sind diese Funktionen zum Teil über alle möglichen Kapitel verteilt, je nach Thema des Kapitels. Einige wenige Funktionen des täglichen Gebrauchs sollen Ihnen den Umgang mit diesen Funktionen verdeutlichen. Neben einigen Funktionen sind in PHP auch mathematische Konstanten definiert, die man bei Berechnungen benötigen könnte. Eigentlich sind nur die beiden ersten Werte aus Tabelle 3.17 konstant. Die anderen Werte ergeben sich aus Berechnungen mit diesen Konstanten. Da bei manchen Berechnungen diese Werte aber gehäuft auftauchen, deren Berechnung aber viel Zeit in Anspruch nimmt, wurden diese Konstanten sozusagen für Sie schon vorbereitet. Tabelle 3.17 Mathematische Konstanten in PHP
154
Konstante
Wert
Bedeutung
M_PI
3.14159265358979323846
Die Kreiszahl π
M_E
2.7182818284590452354
Die Euler´sche Zahl e
M_LOG2E
1.4426950408889634074
Logarithmus zur Basis 2 von e
M_LOG10E
0.43429448190325182765
Logarithmus zur Basis 10 von e
M_LN2
0.69314718055994530942
Natürlicher Logarithmus von 2
M_LN10
2.30258509299404568402
Natürlicher Logarithmus von 10
M_PI_2
1.57079632679489661923
M_PI_4
0.78539816339744830962
M_1_PI
0.31830988618379067154
π/2 π/4 1/π
Sandini Bib Mathematische Funktionen
Konstante
Wert
Bedeutung
M_2_PI
0.63661977236758134308
2/π
M_2_SQRTPI
1.12837916709551257390
2/sqrt(π)
M_SQRT2
1.41421356237309504880
sqrt(2)
M_SQRT1_2
0.70710678118654752440
1/sqrt(2)
Tabelle 3.17 (Forts) Mathematische Konstanten in PHP
In Tabelle 3.18 finden Sie einige subjektiv ausgewählte einfache Funktionen, die mir im Laufe der Zeit recht hilfreich waren. Weitere Funktionen finden Sie im Kapitel „LII. Mathematische Funktionen“ des Handbuches. Funktion Beschreibung abs()
Wert einer Zahl ohne Vorzeichen
round()
Klassische Rundungsfunktion
ceil()
Nächste größere Integerzahl
floor()
Nächste kleinere Integerzahl
max()
Maximum der Übergabeparameter
min()
Minimum der Übergabeparameter
sqrt()
Quadratwurzel
pow()
Potenz zur Basis. pow( $a, 2 ) := a2
sin()
Sinus eines Radianwinkels. Nicht zu verwechseln mit der Funktion sinh().
cos()
Cosinus eines Radianwinkels. Nicht zu verwechseln mit der Funktion cosh().
tan()
Tangens eines Radianwinkels. Nicht zu verwechseln mit der Funktion tanh().
Tabelle 3.18 Einige mathematische Funktionen
dec2rad() Umrechnung Grad in Radian log()
Natürlicher Logarithmus
log10()
Dekatischer Logarithmus
In Listing 3.75 sehen Sie Beispiele für einige dieser Funktionen. Die Ergebnisse können Sie dem Listing 3.76 entnehmen. Die round()-Funktion führt eine mathematische Rundungsfunktion aus, bei der Sie die dezimale Genauigkeit der Funktion übergeben können. In diesem Beispiel soll auf vier Dezimalstellen gerundet werden. Eine bankentechnische Rundung würde hier den Wert 11.4987 ergeben.
155
Sandini Bib 3 Variablen und ihre Datentypen
Bei den trigonometrischen Funktionen sin(), cos(), tan() sind wir es gewohnt, mit Gradangaben zu rechnen. So soll im Listing 3.75 vom Winkel 450 die jeweilige trigonometrische Funktion berechnet werden. Die PHP-Funktionen benötigen aber die Winkelangaben in Radian. Um auf diese Winkelangabe zu gelangen, können Sie die Funktion deg2rad() benutzen. Wenn Sie für eine solche Umrechnung keine Funktion benutzen wollen, können Sie auch mit dem Faktor p / 180 multiplizieren. Nichts anderes macht die Funktion deg2rad(). Listing 3.75 Beispiele für mathematische Funktionen aus Tabelle 3.18
Der Sinus eines Winkels (sin()) ist eine trigonometrische Funktion. Der Sinus Hyperbolicus (sinh()) hat mit Dreiecksberechnungen herzlich wenig zu tun. Eine Verwechslung oder ein „h“ zu viel können interessante Ergebnisse bringen, leider aber auch falsche. Als Beispiel für die Potenzfunktion pow() habe ich die trigonometrische Gleichung sin2(x) + cos2(x) = 1 ausgenutzt. Es werden also die Variablen $sin_val und $cos_val jeweils zur Potenz 2 erhoben, d.h. quadriert. $rounded_val $ceil_val $floor_val $abs_val $max_val $min_val $rad_val $sin_val $sinh_val $cos_val $square_val $log_val
= = = = = = = = = = = =
float(11.4988) float(12) float(11) float(12.3456) int(8) int(1) float(0.78539816339745) float(0.70710678118655) float(0.86867096148601) float(0.70710678118655) float(1) float(1)
Listing 3.76 Rechenergebnisse von Listing 3.75
Eine ähnliche Identität finden Sie in der Berechnung des natürlichen Logarithmus. Die Grundlage des natürlichen Logarithmus ist die Euler´sche Zahl e. Der natürliche Logarithmus dieser Zahl ist 1.
157
Sandini Bib 3 Variablen und ihre Datentypen
3.16.1
Rechengenauigkeit
Ein Computer hat nur einen endlichen, wenn heute auch recht großen Speicherbereich zur Verfügung. Diese Tatsache spielt bei der Berechnung mit Fließkommazahlen eine entscheidende Bedeutung. Dieses Problem trägt die Computertechnik seit ihren Anfängen mit sich. Die Sprache PHP ist also nicht alleine von diesem Problem betroffen. Die beiden Beispielprogramme, die ich Ihnen im Folgenden zeigen werde, sollten Sie einmal mit einer anderen Programmiersprache austesten. Sie werden zu ähnlichen, wenn nicht sogar zu schlechteren Ergebnissen kommen. In Listing 3.77 sehen Sie ein kleines Skript, das nichts weiteres tut, als die Zahl 1/3 aus sich selber zu berechnen. Wenn Sie sich die entscheidende Zeile einmal genau anschauen, passiert dort beim ersten Durchlauf Folgendes: $x = ( 9 * 1/3 + 1 ) * 1/3 – 1 Ë = ( 9/3 + 1 ) / 3 – 1 Ë = ( 3 + 1 ) / 3 – 1 Ë = 4 / 3 – 1 Ë = 1/3
Beim zweiten Durchlauf geschieht exakt das Gleiche. Diese „Nichtveränderung“ der Variablen $x wird in einer Schleife 30 Mal durchgeführt. Eigentlich dürfte sich also bei der Variablen $x nichts tun. Eigentlich ... Wir haben in unserer Berechnung mit rationalen Zahlen gearbeitet. Der Computer arbeitet aber mit Fließkommazahlen (außer Sie arbeiten mit entsprechend teuren Algebra-Systemen). Listing 3.77 Rundungsfehler bei der Berechnung von 1/3
Die Ergebnisse der einzelnen Durchläufe können Sie sich in Listing 3.78 ansehen. In den ersten drei Durchläufen scheint auch nichts zu geschehen. 1/3 ist 0.333333333333 ... Aber schon beim vierten Durchlauf gibt es eine Abweichung. Und diese Abweichung wächst von Durchlauf zu Durchlauf um rund den Faktor 10.
158
Sandini Bib Mathematische Funktionen
1 - 0.33333333333333 2 - 0.33333333333333 3 - 0.33333333333333 4 - 0.33333333333331 5 - 0.33333333333316 6 - 0.33333333333209 7 - 0.33333333332463 8 - 0.33333333327238 9 - 0.33333333290665 10 - 0.33333333034657 11 - 0.33333331242597 12 - 0.33333318698176 13 - 0.33333230887252 14 - 0.33332616211705 15 - 0.33328313528222 16 - 0.33298196965413 17 - 0.33087489868681 18 - 0.31617868591584 19 - 0.21589933876306 20 - -0.36458794093202 21 - -0.16826864087455 22 - -0.91343962135864 23 - 5.5959078554516 24 - 286.4235703958 25 - 738631.57867489 26 - 4910190219772.4 27 - 2.1698971194914E+026 28 - 4.2376081582594E+053 29 - 1.6161590612652E+108 30 - 2.3507731001786E+217
Listing 3.78 Rechenungenauigkeiten aus Listing 3.77
Am Ende der Berechnung haben Sie einen Fehler, der fast die Darstellungsmöglichkeiten von 64 Bit IEEE-Zahlen sprengt. Denn nach diesem Standard werden in PHP Dezimalzahlen dargestellt. Wenn Sie der Meinung sind, dass diese Berechnung einer Identität etwas kompliziert ist, werfen Sie einen Blick auf Listing 3.79. Ein recht kleiner Wert wird 27 Mal quadriert. Das Ergebnis dieser Berechnung muss bei einer Genauigkeit von 10 Stellen exakt 647.530,4707 lauten.
159
Sandini Bib 3 Variablen und ihre Datentypen
Wenn Sie das Programm laufen lassen, bekommen Sie eine Liste mit Werten, von denen Sie die letzten vier in Listing 3.80 sehen. Es existiert eine Abweichung an der dritten Nachkommastelle. Listing 3.80 Aufschaukeln der „Rundungsfehler“ aus Listing 3.79
24 25 26 27
-
5.3533445600846 28.658297978988 821.29804305245 674530.47552179
Sie können die Berechnung des Quadrats innerhalb der Schleife auch auf zwei anderen Wegen durchführen. Sie können den zusammengesetzten Operator *= einsetzen, denn die Berechnung im Listing entspricht der Zeile $x *= $x;
Die dritte Variante liegt in der Nutzung der Funktion Berechnung des Quadrats können Sie mit
pow().
Denn die
$x = pow($x, 2);
bewerkstelligen. In allen drei Berechnungsvarianten wird das Ergebnis aus Listing 3.80 errechnet. Wenn Sie Berechnungen durchführen müssen, die solche Ungenauigkeiten nicht vertragen, müssen Sie auf die Berechnung beliebig genauer Zahlen ausweichen. Die Berechnung solcher Zahlen ist zwar genau, aber zeit- und ressourcenaufwändig. Sie sollten diese Art der Berechnung nur dann durchführen, wenn Sie wirklich nicht anders können. In PHP finden Sie hierzu die so genannten bcmath-Funktionen. Der Name leitet sich von der Art der Zahlen her, mit denen hier gerechnet wird. Es handelt sich um so genannte BCD-Zahlen – Binary Coded Decimal. Diese Zahlen kommen überall dort zum Einsatz, wo größtmögliche Genauigkeit gefordert ist. Diese Zahlen sind für bestimmte Berechnungen seit langer Zeit sogar vorgeschrieben. Sie gab es schon in den ersten Versionen der Programmiersprache COBOL, einer Sprache, die auch heute noch im kaufmännischen und bankentechnischen Bereich eingesetzt wird. Mit den bcmath-Funktionen können Sie dem Paroli bieten.
160
Sandini Bib Mathematische Funktionen
Funktion
Bedeutung
bcadd()
Beliebig genaue Addition
bcsub()
Beliebig genaue Subtraktion
bcmul()
Beliebig genaue Multiplikation
bcdiv()
Beliebig genaue Division
bcmod()
Beliebig genaue Modulo-Division
bcpow()
Beliebig genaue Potenz
bcsqrt()
Beliebig genaue Quadratwurzel
bcscale()
Setzen der Genauigkeit
bccomp()
Vergleich zweier beliebig genauer Zahlen
bcpowmod()
Kombination aus bcpow() und bcmod()
Tabelle 3.19 Funktionen für die Berechnung mit beliebiger Genauigkeit
In unserem letzten Beispiel muss die Berechnung des Quadrats durch die Zeile $x = bcpow($x, 2, 20);
ersetzt werden. Diese Anweisung besagt, dass die Variable $x quadriert werden soll. Und dies mit einer Genauigkeit von 20 Stellen. In Listing 3.81 sehen Sie die letzten vier Zeilen der Ausgabe des Skriptes aus Listing 3.79. Was Sie aber auch erkennen können, ist der bis jetzt unausgesprochene Unterschied zwischen der Genauigkeit des Ergebnisses und der Genauigkeit der Berechnungen auf dem Weg dorthin! 24 25 26 27
-
5.35334455534169546566 28.65829792820657514623 821.29804014184927735440 674530.47074084266695329142
Listing 3.81 Ergebnis der Berechnung mit bcpow()
Als Faustregel kann man sagen, dass man bei einer gewünschten Genauigkeit des Ergebnisses von n die Berechnung mit einer Genauigkeit von 2 * n durchführen muss! Dies sehen Sie auch an unserem Beispiel. Das Ergebnis sollte auf zehn Stellen genau sein. Die Berechnung haben wir mit 20 Stellen durchgeführt und das richtige Ergebnis erhalten.
161
Sandini Bib 3 Variablen und ihre Datentypen
3.17 Zeichenketten Obwohl die Computer für die Berechnung komplexer mathematischer und physikalischer Aufgaben entwickelt wurde, zählen die Zeichenketten heute mit zu den wichtigsten Datentypen, die ein Computer verarbeiten kann. Dies geht vom einfachen Anzeigen von Text, wie der Aufforderung, einen Wert über die Tastatur einzugeben, bis zum komplexen Vorgang, einen Satz zu verstehen und entsprechende Aktionen auszuführen. Das letzte Beispiel würde als Anwendung sicherlich den Rahmen sprengen, aber das „Verstehen“ von Benutzereingaben gehört sicherlich noch nicht dazu. Zudem gehört es zu den wichtigen Tätigkeiten eines Programms! „Never Trust User Input!“ – dies sollte derzeit zum Standard der Programmentwicklung gehören. Mit den Auswirkungen falsch verstandener Benutzerfreiheiten werden wir uns noch beschäftigen. Jede manuelle Benutzereingabe, die PHP verarbeiten kann, wird zuerst über die Tastatur entgegengenommen, sei dies über ein Webformular oder auf Kommandozeilenebene geschehen. Und damit handelt es sich erst einmal um eine Zeichenkette, die wir anschließend in einen anderen Datentyp konvertieren können – wenn wir wollen. Bisher sind uns Zeichenketten als schmückendes Beiwerk für die Ausgabe von Texten begegnet. Und wir haben nur eine Art von Zeichenketten benutzt. Es gibt aber deren zwei. Diese beiden Arten unterscheiden sich in der Art, wie diese Zeichenketten „umklammert“ werden. In der uns schon bekannten Art wird eine Zeichenkette mit den bekannten Anführungszeichen, auch „doppelte Hochkommata“ genannt, umschlossen. Die zweite Art benutzt die einfachen Hochkommata „’“. In Listing 3.82 sehen Sie für beide Arten jeweils ein Beispiel. Es handelt sich jeweils um eine einfache Zeichenkette, die mit dem Zeilenumbruch \n beendet wird. Listing 3.82 Zwei Arten von Zeichenketten
162
Sandini Bib Zeichenketten
Die Ausgabe dieses kleinen Programms sehen Sie in Abbildung 3.4. In der Zeichenkette mit den doppelten Hochkommata werden Sonderzeichen, wie beispielsweise das Zeichen für den Zeilenumbruch, interpretiert und ausgeführt. Die Zeichenkette mit den einfachen Hochkommata wird exakt so ausgegeben, wie Sie diesen Text geschrieben haben. Es findet keinerlei Interpretation der Zeichen in dieser Zeichenkette statt. Damit wird das Sonderzeichen für den Zeilenumbruch auch nicht interpretiert, sondern exakt so ausgegeben. Dies erkennen Sie auch daran, dass die folgende Zeichenkette direkt hinter dem \n beginnt. Wenn Sie den Wert einer Variablen ausgeben möchten, so können Sie dies auch nur mit Zeichenketten in doppelten Hochkommata. In Listing 3.83 sehen Sie hierfür ein Beispiel. Die beiden echo-Befehle sind bis auf die Art der Hochkommata identisch. Abbildung 3.4 Zwei Arten von Zeichenketten
Wenn Sie sich die Abbildung 3.5 anschauen, werden Sie den Unterschied sofort erkennen. Die Variable wird ebenfalls nicht interpretiert, sondern als normale Zeichenkette dargestellt. Wenn Sie also in einer Zeichenkette etwas haben, was von PHP interpretiert werden soll, müssen Sie die Zeichenkette in doppelte Hochkommata setzen. Ist es ein reiner Text, spielt es keine Rolle, welche Form der Zeichenkette Sie benutzen.
163
Sandini Bib 3 Variablen und ihre Datentypen
Wenn eine Variable selber eine Zeichenkette beinhaltet, spielt es dann eine Rolle, mit welchen Hochkommata die Variable deklariert wurde? In den meisten Fällen kann man dies mit Nein beantworten. Sehen Sie sich hierzu einmal das Listing 3.84 an. Es werden zwei Zeichenketten-Variablen deklariert, die anschließend in unterschiedlicher Art ausgegeben werden. Abbildung 3.5 Variable in unterschiedlichen Zeichenkettenarten
Listing 3.84 Zeichenkettenvariable in der Ausgabe
Das Problem beginnt, wenn Sie die Variable als Bestandteil eines längeren Wortes benutzen wollen. In unserem Beispiel wird versucht, ein „s“ an den Inhalt der Variablen zu hängen. Dies führt im ersten Versuch zu einer falschen Ausgabe (Abbildung 3.6). Der Inhalt der Variablen wird
164
Sandini Bib Zeichenketten
nicht ausgegeben. PHP interpretiert $zeichen_variable_1s als neue, nicht deklarierte Variable. Da eine solche Variable bei Zeichenketten mit der leeren Zeichenkette "" initialisiert wird, wird nur der schließende Punkt ausgegeben. Damit PHP erkennt, wo die Variable beginnt und wo sie endet, muss sie in solchen Fällen von den geschweiften Klammern { und } eingerahmt werden. Abbildung 3.6 Ausgabe aus Listing 3.84
Wenn Sie diese Regel anwenden, wird die Variable wie gewünscht ausgegeben. An den letzten drei echo-Befehlen und der Ausgabe erkennen Sie, dass diese Regeln auch für Zeichenketten-Variablen in doppelten Hochkommata gelten. Wenn Sie Variablen schachteln, müssen Sie allerdings aufpassen, dass Sie nicht an einer Stelle im Programm die „falschen“ Hochkommata benutzt haben. In Listing 3.86 sehen Sie eine solche Schachtelung in verkürzter Form. Eine nummerische Variable wird in eine Zeichenkette eingebettet, die den Wert um eine Maßeinheit erweitert. Dieses Ergebnis wird dann in eine weitere Zeichenkette eingebettet. In der Praxis kann so etwas vorkommen, wenn Sie beispielsweise, je nach Größenordnung eines Rechenergebnisses, „cm“, „m“ oder „km“ als Einheit benutzen. Auf diese Weise muss nicht der gesamte Zeichenkettenausdruck (in diesem Beispiel $aeussere_variable) wiederholt werden. Er steht nur einmal im Hauptspeicher! Die Ausgabe dieses kleinen Skripts lautet: Das Ergebnis lautet: 1.5 cm
Listing 3.85 Ausgabe von Listing 3.86
165
Sandini Bib 3 Variablen und ihre Datentypen
Listing 3.86 Geschachtelte Zeichenketten
Wer sich schon einmal mit einer anderen Programmiersprache wie beispielsweise C/C++, Pascal oder C# auseinander gesetzt hat, wird die Möglichkeit kennen, auf die einzelnen Buchstaben einer Zeichenkette zugreifen zu können. PHP macht hier keine Ausnahme. Die Methode, sich einen einzelnen Buchstaben aus einer Zeichenkette heraus zu betrachten, ist in all diesen Sprachen ähnlich gelöst. In Listing 3.87 sehen Sie eine Lösung für PHP. Listing 3.87 Betrachtung einzelner Buchstaben
In der Variablen $string wird die Zeichenkette „Zeichenkette“ abgespeichert. In der zählergesteuerten Schleife wird, mit null beginnend, Buchstabe für Buchstabe erst der Variablen $buchstabe zugeordnet und anschließend ausgegeben. Achten Sie darauf, dass auf die einzelnen Buchstaben mit { und } zugegriffen wird. Diese Regelung gilt ab PHP5. In älteren Versionen finden Sie noch eine Schreibweise mit [ und ]. Diese gilt als veraltet und sollte nicht mehr angewandt werden. Sie ist nur noch aus Kompatibilitätsgründen Bestandteil der neuen Version!
166
Sandini Bib Zeichenketten
Einen Lauf dieses Programms sehen Sie in Abbildung 3.7. Zum jetzigen Zeitpunkt müssen Sie in diesem Beispiel noch wissen, wie viele Buchstaben die Variable enthält. Dies ist bei wechselnden Zeichenketten sicherlich nicht sinnvoll. PHP ist an dieser Stelle aber sehr fehlertolerant. Wenn Sie sich verzählen sollten, wird Ihnen standardmäßig kein Fehler angezeigt. Abbildung 3.7 Ausgabe einzelner Buchstaben einer Zeichenkette
Wenn Sie sich das Listing 3.88 anschauen, entspricht es dem Listing 3.87 mit einer Ausnahme: Es wird in der Schleife versucht, 15 Buchstaben auszugeben. In Sprachen wie C/C++ oder C# würde dies zu einem Fehler führen.
Nicht so in PHP. Sie ahnen es bereits. Da es diese Variablen nicht gibt, werden sie mit einer leeren Zeichenkette vorbelegt und ausgegeben. In Abbildung 3.8 sehen Sie, dass dieses Programm einwandfrei ausgeführt wird.
167
Sandini Bib 3 Variablen und ihre Datentypen
Abbildung 3.8 Ausgabe zu vieler Buchstaben einer Zeichenkette
Wie bei den nummerischen Datentypen können Sie auch bei Zeichenketten die Umwandlung des Datentyps erzwingen. Dafür gibt es den Typ-Cast (string). In Listing 3.89 wird eine nummerische Variable mit dem Fließkommawert 23,6 zu einer Zeichenkette mit den „Buchstaben“ 2, 3, „. und 6 umgewandelt. Listing 3.89 Typ-Cast auf String
Wenn Sie dieses Programm ausführen, erhalten Sie die Ausgabe: float(23.6) string(4) "23.6"
Bisher haben Sie als einziges Sonderzeichen den Wagenrücklauf \n kennen gelernt. Was ist aber zum Beispiel, wenn Sie als Bestandteil der Zeichenkette die Anführungszeichen benutzen wollen. Wenn Sie den Satz „Der Name lautet „Mustermann““ direkt einer Variablen zuordnen oder ausgeben, werden Sie einen Fehler gemeldet bekommen. PHP interpretiert diesen Satz nach dem Schema:
168
Sandini Bib Zeichenketten
1. Zeichenkette „Der Name lautet „ 2. Mustermann 3. Zeichenkette „“ (leer) An der zweiten Position dieser Interpretation steht etwas, das PHP nicht interpretieren kann. Es handelt sich nicht um eine Variable, da das $Zeichen fehlt. Ein Wort aus dem PHP-Wortschatz ist es ebenfalls nicht. PHP meldet sich also mit dem Fehler: Parse error: syntax error, unexpected T_STRING, expecting ',' or ';' in C:\Programme\Apache Group\Apache2\htdocs\zeichen_variable10.php on line 3
Zeichenfolge
Bedeutung
\n
Zeilenvorschub (LF oder 0x0A als ASCII-Code)
\r
Wagenrücklauf (CR oder 0x0D als ASCII-Code)
\t
Horizontal-Tabulator (HT oder 0x09 als ASCII-Code)
\\
Backslash
\$
Dollar-Symbol
\"
Doppelte Anführungszeichen als Bestandteil der Zeichenkette
\[0-7]{1,3}
Oktale Zahl, \010 (okt) = 8 (dez)
\x[0-9A-Fa-f]{1,2}
Hexadezimale Zahl, \x10 (hex) = 16 (dez)
Tabelle 3.20 Sonderzeichen in Zeichenketten
Hier hilft die Tabelle 3.20 weiter. Hier finden Sie den Hinweis, dass vor dem darzustellenden Anführungszeichen der Backslash stehen muss. In Listing 3.90 wird dieser Satz in der gültigen Syntax dargestellt.
Der zweite echo-Befehl in Listing 3.90 zeigt neben den Anführungszeichen noch die Darstellung des Backslashs selber. Die Ausgabe dieses Skripts finden Sie in Listing 3.91.
169
Sandini Bib 3 Variablen und ihre Datentypen
Listing 3.91 Ausgabe von Sonderzeichen (Listing 3.90)
Der Name lautet "Mustermann" Dies ist nicht "t", sondern \t
Bei der Behandlung nummerischer Datentypen haben Sie das Prä- und Post-Inkrement und -Dekrement kennen gelernt. Sie können diese Operation auch mit Zeichenketten durchführen! Schauen Sie sich dazu einmal das Listing 3.92 an. Listing 3.92 Inkrement-Operator bei Zeichenketten
Es wird eine Zeichenketten-Variable mit dem Buchstaben „A“ als Wert deklariert. Dann wird diese Variable inkrementiert und ausgegeben. Wie Sie am Listing 3.93 sehen, hat sich der Inhalt der Variablen in „B“ verändert. Eigentlich auch logisch, ist doch „B“ der auf „A“ folgende Buchstabe. Das Geheimnis ist allerdings etwas profaner angelegt. Listing 3.93 Ergebnisse aus Listing 3.92
string(1) "B" string(3) "Aam"
Der Buchstabe „A“ hat im ASCII-Zeichensatz den Wert 65. Wenn Sie den Wert 65 inkrementieren, erhalten Sie 66, was dem Buchstaben „B“ im ASCII-Zeichensatz entspricht. Im zweiten Beispiel sehen Sie eine komplette Zeichenkette. Wenn Sie diese inkrementieren, wird der letzte Buchstabe der Zeichenkette um 1 hochgezählt, aus „l“ wird „m“. Sie können natürlich auch dekrementieren. Sie sollten in jedem Fall an den Grenzen des Alphabets aufpassen.
3.18 Heredoc – Zeichenketten Eine Besonderheit bei den Zeichenketten bieten die so genannten Heredoc-Zeichenketten. Mit ihnen kann man längere Textpassagen durchgehend schreiben, ohne diese längere Zeichenkette Stück für Stück zusammenzubauen.
170
Sandini Bib Heredoc – Zeichenketten
Wichtig bei Heredoc-Zeichenketten ist die Stopp-Zeichenkette, mit der PHP mitgeteilt wird, dass an dieser Stelle das Ende des Heredoc erreicht ist. Sie bestimmen diese Zeichenkette mit den einleitenden
Sollte die Verbindung zustande kommen, können Sie mit dem Datenbank-Handle weitere Funktionen für diese Datenbank aufrufen. Das Datenbank-Handle ist im Ablauf des Skripts eindeutig. Sie können also verschiedene Datenbanken gleichzeitig geöffnet haben. Sie müssen nur dafür Sorge tragen, dass diese Handles in verschiedenen Variablen abgelegt werden. In Listing 8.6 wird bei gelungener Verbindung die Funktion mysqli_get_host_info() aufgerufen. Diese gibt eine Zeichenkette zurück, die Ihnen den Hostnamen des Datenbankservers und die Verbindungsart liefert. In Abbildung 8.9 sehen Sie die Browserausgabe des Skripts aus Listing 8.6.
434
Sandini Bib Verbindungen zwischen PHP und MySQL
Wenn Sie die Verbindung zur Datenbank nicht mehr benötigen, sollten Sie diese Verbindung über die Funktion mysqli_close() schnellstmöglich wieder schließen. Eine Datenbankverbindung ist relativ ressourcenintensiv, und je weniger Ressourcen Sie verbrauchen, umso besser. Abbildung 8.9 Ausgabe des Skripts aus Listing 8.6
Unter der alten Schnittstelle gab es noch die Funktion mysql_pconnect(), die eine Verbindung dauerhaft eingerichtet hat (permanent). Diese Funktion gibt es unter MYSQLI nicht mehr.
8.5.2 Objektorientierte Verbindung ohne Optionen Bei der objektorientierten Verbindung wird nicht ein Datenbank-Handle erzeugt, sondern ein Zugriffsobjekt, über das Sie den Zugang zur Datenbank regeln. Ein solches Zugriffsobjekt erhalten Sie über die Instanziierung der Klasse mysqli. In Listing 8.7 wird auf diese Art eine Verbindung zum Datenbankserver aufgebaut. Sie können auch hier wieder die Datenbank mit angeben. Um eine andere Form der Datenbankauswahl zu demonstrieren, wird an dieser Stelle die Datenbank nicht mit angegeben. Ob ein Objekt erstellt wurde, können Sie über die Bedingung (! dbh) einer if-Abfrage feststellen. In Listing 8.7 wird die Fehlerabfrage über die Funktion mysqli_connect_errno() durchgeführt. Wie Sie sehen, können Sie auch bei der Arbeit mit Objekten über diese Funktion auf evtl. aufgetretene Fehler testen. In diesem Fall müssen Sie es sogar, da im Fehlerfall kein Objekt erstellt wird. Datenbank
Listing 8.7 Einfacher objektorientierter Datenbankzugriff
435
Sandini Bib 8 MySQL
Listing 8.7 (Forts.) Einfacher objektorientierter Datenbankzugriff
Datenbank Objektorientierte Verbindung
Ist das Verbindungsobjekt $dbh ordnungsgemäß erstellt worden, können Sie mit der Methode select_db() dieses Objekts die Datenbank festlegen, mit der Sie arbeiten wollen. Wenn Sie mit mehreren Datenbanken gleichzeitig arbeiten, müssen Sie für jede Datenbank ein eigenständiges Verbindungsobjekt anlegen. Bei existierendem Verbindungsobjekt können Sie auch über die Objekteigenschaften errno und error auf einen evtl. aufgetretenen Fehler reagieren. Sie greifen daher über $dbh->errno; $dbh->error;
436
Sandini Bib Verbindungen zwischen PHP und MySQL
auf die Fehlereigenschaften zu, sollte das Objekt wie in Listing 8.7 mit $dbh benannt sein. Wie im klassischen Fall des Funktionszugriffs sollten Sie die Verbindung so früh wie möglich schließen. Dazu benutzen Sie die Methode close() der mysqli-Klasse.
8.5.3 Objektorientierte Verbindung mit Optionen Wenn Sie die Art und das Verhalten der Datenbankverbindung beeinflussen wollen, müssen Sie mit einer anderen Methodik vorgehen. Mit der Funktion mysqli_init() erstellen Sie sich ein Verbindungsobjekt, das aber noch keine reale Verbindung zur Datenbank hergestellt hat. Diesem Verbindungsobjekt können Sie mit der Methode options() einige Einstellungen mit auf den Weg geben. Option
Bedeutung
MYSQLI_READ_DEFAULT_GROUP
Liest die Optionen für die angegebene Gruppe aus der MySQL-Konfigurationsdatei.
MYSQLI_READ_DEFAULT_FILE
Gibt den Namen der Konfigurationsdatei an, sollte es sich nicht um die Datei my.cnf handeln.
Tabelle 8.1 Optionen für die Methode options() der mysqli-Klasse
MYSQLI_OPT_CONNECT_TIMEOUT Timeout für die Verbindung. MYSQLI_OPT_LOCAL_INFILE
Gestattet die Nutzung des Befehls LOAD LOCAL INFILE.
MYSQLI_INIT_COMMAND
Der hiermit übergebene MySQL-Befehl wird bei jeder (Neu-)Verbindung ausgeführt.
Eine Übersicht der möglichen Optionen finden Sie in der Tabelle 8.1. In Listing 8.8 wird auf diese Weise die Timeout-Zeit auf zehn Sekunden gesetzt. Wollen Sie mehrere Optionen setzen, müssen Sie die Methode mehrfach mit geänderten Parametern aufrufen. Sind alle Optionen gesetzt, erstellen Sie die eigentliche Verbindung zur Datenbank mit der Methode real_connect(). Die Parameter dieser Methode stimmen mit denen des Klassenkonstruktors überein. Sie können dieser Methode aber zusätzlich noch einen Parameter übergeben, der ebenfalls Einfluss auf die Verbindung hat, ähnlich den Optionen bei der Initialisierung der Verbindung.
437
Sandini Bib 8 MySQL
Tabelle 8.2 Optionen der Methode mysqli_real_connect()
Option
Bedeutung
MYSQLI_CLIENT_COMPRESS
Die Daten werden für die Übertragung komprimiert. Dies kann bei einer großen Datenmenge und einer langsamen Leitung erhebliche Geschwindigkeitsverbesserungen zur Folge haben.
MYSQLI_CLIENT_FOUND_ROWS
Liefert die Anzahl der gefundenen Datensätze zurück. Üblicherweise wird die Anzahl der geänderten Zeilen zurückgegeben.
MYSQLI_CLIENT_IGNORE_SPACE Gestattet Freizeichen nach MySQL-Funktionen. MYSQLI_CLIENT_INTERACTIVE
Wenn Sie in der Konfigurationsdatei keine Änderungen zwischen INTERACTIVE TIMEOUT und WAIT TIMEOUT gemacht haben, ist diese Option ohne Auswirkung.
MYSQLI_CLIENT_SSL
Benutzt SSL-Verschlüsselung für den Datentransfer. Dazu muss natürlich SSL vorhanden und aktiv sein.
Ab dem Zeitpunkt der realen Verbindung gibt es keinen Unterschied in der Programmierung mehr. Sie gehen also im weiteren Verlauf des Skripts wie bei den Verbindungen ohne Optionen vor. Listing 8.8 Objektorientierter Datenbankzugriff mit Optionen
Datenbank Datenbank
8.6
Daten lesen
Nun beschränkt sich die Arbeit mit Datenbanken nicht nur auf das Öffnen und Schließen von Verbindungen :-) Sie wollen sich zumindest die Daten in einer Datenbank anzeigen lassen. In Listing 8.9 wird nach der Erstellung einer Verbindung zur Datenbank problems der gesamte Inhalt der Tabelle priority ausgelesen. Im Konstruktor der Klasse mysqli wird in Listing 8.9 das Passwort nicht mit übergeben, da es wie in den Beispielen vorher nicht existiert. Bisher haben wir aber an dieser Stelle eine leere Zeichenkette mit übergeben. Dies ist aber nicht zwingend notwendig. Der Methode query() übergeben Sie den SQL-Befehl, den Sie an die Datenbank absetzen wollen. Dies kann jeder gültige SQL-Befehl sein, also auch ein Befehl wie in Listing 8.5 angezeigt. Im Fall des Listing 8.9
439
Sandini Bib 8 MySQL
wird der SQL-Befehl select * from priority der Datenbank übergeben. Bei der Bearbeitung der SQL-Anweisungen muss man an dieser Stelle zwischen SQL-Anweisungen unterscheiden, die ein Resultat zurückliefern wie beispielsweise die Anweisung select ..., oder solchen, die eben dies nicht tun, wie insert ... Wenn dieser Befehl ordnungsgemäß ausgeführt werden konnte, befindet sich in der Variablen $table_rows ein Ergebnisobjekt mit allen Zeilen und Feldern der Tabelle priority. In Listing 8.9 wird der Inhalt dieses Ergebnisobjektes über eine whileSchleife als HTML-Tabelle ausgegeben. Dazu wird das Ergebnisobjekt zeilenweise durchlaufen. In Listing 8.9 wird dazu jede Datenbankzeile als assoziatives Array mit der Methode fetch_assoc() der Variablen $row zugewiesen. In diesem assoziativen Array können Sie nun über die Feldnamen der Tabelle auf die Werte der einzelnen Tabellenspalten der gerade aktuellen Datenbankzeile (Datensatz) zugreifen. So erhalten Sie über $row['id'] den Wert des Datenbankfeldes id. Listing 8.9 Daten aus einer Datenbanktabelle lesen und anzeigen
Datenbank Datenbank Datenbank lesen