Nur Syntax-Check, keine Ausführung des Programms
php -l test.php
Verbindung/Addition von String-Variablen werden durch den „.“ dargestellt. Beispiele:
$titel = $titel . ", hallo Essen"; # oder $titel .= ", hallo Essen"; # oder $titel = $basistitel . ", " . $spezialtitel; # oder echo "<h1>".$titel."</h1>";
Ausgaben können mit dem Befehl „echo“ oder etwas eleganter mit dem Befehl „printf“ erzeugt werden.
echo "<p>Ausgabe Wert: " . $wert1 . "</p>"; // printf("<p>Ausgabe Wert: %d</p>", $wert1); printf("<p>Ausgabe Wert: %s</p>", $wert1); // %d = Int (Dezimal) // %s = String // %c = Char // %h = Hexadezimal // %o = Oktal
<?php $wert = 20; printf("Wert dezimal: %d\n", $wert); printf("Wert hexadezimal: %x\n", $wert); printf("Wert oktal: %o\n", $wert); $wert = 024; // oktale Schreibweise printf("Wert dezimal: %d\n", $wert); $wert = 0x14; printf("Wert hexadezimal: %d\n", $wert);
Einfache Anführungszeichen (') geben die Zeichenkette wieder (ohne Auswertung). Mit doppelten Hochkommata („) erfolgt eine Auswertung der verwendeten Sonderzeichen (z.B. $, wenn eine Variable enthalten ist).
Geschweifte Klammern können genutzt werden, um das Ende einer Variablen zu definieren.
//... $op2 = "2"; $wert = "{$op2}2"; // $wert hat damit den Wert "22" //Alternativ könnte geschrieben werden $wert = "$op2" . "2"; /...
Berechnung innerhalb einer echo-Anweisung. Wichtig sind dabei die runden Klammern.
#... echo "<p>Addition: " . ($wert1 + $wert2) . "</p>"; #...
Berechnung mit Zuweisung zu einer neuen Variablen:
#... $ergebnis = $wert1 - $wert2; echo "<p>Substraktion: {$ergebnis}</p>"; # Die geschweiften Klammern sind in diesem Beispiel nicht zwingend erforderlich. # Dienen aber im PHP dazu, anzugeben, dass der Inhalt der Klammern ausgewertet # werden soll. #...
Mit der Funktion „error_log()“ kann direkt ins Apache-Error-Log geschrieben werden. Dies wird in erster Linie für Debug-Informationen genutzt.
//... error_log("belieber Text oder Variablen"); //...
Zur Umwandlung zwischen den verschiedenen Zahlensystemen.
<?php $wert = 20; printf("Wert dezimal: %d\n", $wert); // Ausgabe: "Wert dezimal: 20" printf("Wert hexadezimal: %x\n", $wert); // Ausgabe: "Wert dezimal: 14" printf("Wert oktal: %o\n", $wert); // Ausgabe: "Wert oktal: 24" $wert = 024; // oktale Schreibweise printf("Wert dezimal: %d\n", $wert); // Ausgabe: "Wert dezimal: 20" $wert = 0x14; printf("Wert hexadezimal: %d\n", $wert); // Ausgabe: "Wert hexadezimal: 20" echo "\n"; $wert = octdec("24"); echo "Wert: " . $wert . "\n"; // Ausgabe: "Wert: 20" echo "\n"; $wert = hexdec("14"); echo "Wert: " . $wert . "\n"; // Ausgabe: "Wert: 20"
<?php $zahl = 9; $teiler = 5; echo $zahl / $teiler; echo "\n"; // Ausgabe: "1.8" echo "gerundete Division: "; echo round($zahl / $teiler); echo "\n"; // Ausgabe: "gerundete Division: 2" echo "integer Division: "; //ganzzahlige Division echo (int)($zahl / $teiler); echo "\n"; // Ausgabe: "integer Division: 1" echo "integer Division mit Rest aka modulo: "; //nicht teilbarer Rest einer ganzzahligen Division echo $zahl % $teiler; echo "\n"; // Ausgabe: "integer Division mit Rest aka modulo: 4"
Praktisches Beispiel für den modulo-Operator: „Es sollen nur gerade Zahlen ausgegeben werden“
<?php $zahl = 0; while ($zahl <= 15) { // Alle geraden Zahlen ausgeben, ungerade überspringen if ($zahl % 2 == 0) { //modulo Operator echo $zahl . "\n"; } $zahl++; }
„strlen()“ liefert die Länge eines Strings zurück.
<?php $text = "abcdef"; printf("Länge: %d\n", strlen($text)); // Ausgabe: "Länge: 6" //mit dem Stringkonkatenator "." kann innerhalb von strlen auch gearbeitet werden. printf("Länge: %d\n", strlen($text."GHI")); // Ausgabe: "Länge: 9"
Mit „substr“ kann ein Teil einer Zeichenkette ausgegeben werden. Dabei werden als Parameter der String (oder Variable), das Startzeichen und die Länge mitgegeben.
//... <?php $text = "abcdef"; printf("Länge: %d\n", strlen($text)); // strlen = Länge der Zeichenkette printf("erste drei ziechen: %s\n", substr($text, 0, 3)); // 0= Anfang der Zeichenkette, // 3= Anzahl der Zeichen printf("Zeichen ab Pos. 4: %s\n", substr($text, 4)); // 4=Anfang der Zeichenkette // kein 2. Wert, daher bis Ende printf("Letztes Zeichen: %s\n", substr($text, -1)); printf("Letzten 3 Zeichen: %s\n", substr($text, -3)); printf("Mittlere Zeichen: %s\n", substr($text, 2, -2)); //...
Das kann auch mit anderen Stringfunktionen wie „strlen“ kombiniert werden. „strlen“ liefert dabei in diesem Beispiel die Länge des Strings (minus 2).
// ... // substring Ausgabe von $tn_liste (Anfang Zeichen 0, Ende Stringlänge - 2) echo substr($tn_liste, 0, strlen($tn_liste) - 2); // Alternativ: Die LETZTEN 2 Zeichen sollen nicht übernommen werden // echo substr($tn_liste, 0, -2); // ...
Mit den „trim“-Befehlen werden führende oder schließende Whitespaces (Leerzeichen) entfernt.
<?php $text = " ab cd "; printf("'%s'\n", $text); printf("'%s'\n", rtrim($text)); // Löscht die Leerzeichen auf der rechten Seite printf("'%s'\n", ltrim($text)); // Löscht die Leerzeichen auf der linken Seite printf("'%s'\n", trim($text)); // Löscht die Leerzeichen am Anfang und am Ende // --> Ausgabe //' ab cd ' //' ab cd' //'ab cd ' //'ab cd'
Zum Ersetzen von Zeichen innerhalb einer Zeichenkette, kann str_replace() verwendet werden. str_replace() arbeitet dabei überall in der Zeichenkette, auch am Anfang, oder Ende.
$text = "ab cd"; $text = str_replace(" ", "_", $text); printf("'%s'\n", $text); // --> Ausgabe // 'ab_cd'
Sollen mehrere Zeichen ersetzt werden, kann auch innerhalb von str_replace mit Arrays gearbeitet werden.
$text = "/ab cd/"; $text = trim($text); //$text = str_replace(array(" ","/"), array("_","-"), $text); $text = str_replace([" ","/"], ["_","-"], $text); // neue Schreibweise ab php 5.4 printf("'%s'\n", $text); // --> Ausgabe // '-ab_cd-'
Mit „strtoupper()“ bzw „strtolower()“ werden alle Zeichen eines Strings zu Groß- bzw. Kleinbuchstaben umgewandelt werden.
„ucfirst()“ bzw. „lcfirst()“ wandelt entsprechend nur den ersten Buchstabe in Groß- (ucfirst) bzw. Kleinbuchstaben (lcfirst) um.
$text = "WilDeR NaMe"; printf("%s wird zu %s\n", $text, strtoupper($text)); printf("%s wird zu %s\n", $text, strtolower($text)); printf("%s wird zu %s\n", $text, ucfirst($text)); printf("%s wird zu %s\n", $text, lcfirst($text)); // --> Ausgabe // wilDeR NaMe wird zu WILDER NAME // wilDeR NaMe wird zu wilder name // wilDeR NaMe wird zu WilDeR NaMe // wilDeR NaMe wird zu wilDeR NaMe
<?php $wort1 = "der"; $wort2 = "die"; printf("%s < %s: %s\n", $wort1, $wort2, $wort1 < $wort2); printf("%s == %s: %s\n", $wort1, $wort2, $wort1 == $wort2); printf("%s > %s: %s\n", $wort1, $wort2, $wort1 > $wort2); printf("%s cmp %s: %s\n", $wort1, $wort2, strcmp($wort1, $wort2));
Sortiert ein Array auf Grund einer benutzerdefinierten Vergleichfunktion. Bei der Sortierung ist man dabei vollkommen frei.
<?php function cmpi($a, $b) { $a = strtolower($a); $b = strtolower($b); $ergebnis = strcmp($a, $b); return $ergebnis; } $worte = array("der", "die", "das", "wieso", "weshalb", "warum"); sort($worte); printf("Sortiert: %s\n", implode(",", $worte)); $worte = array("der", "die", "Das", "Wieso", "weshalb", "warum"); sort($worte); printf("Sortiert: %s\n", implode(",", $worte)); usort($worte, "cmpi"); //usort = user-defined sort printf("Sortiert: %s\n", implode(",", $worte));
Weiteres Beispiel:
<?php // Mehrdimensionales Array $array = array(array("Git", 10), array("PHP", 1), array("Phython", 4), array("Android", 8), array("PHP 2", 8), array("Quadcopter", 12)); function print_array($twodim) { foreach($twodim as $inner) { // %10s = 10 Stellen breit, rechtsbündig // %-10s = 10 Stellen breit, linksbündig printf("%10s %d\n", $inner[0], $inner[1]); } echo str_repeat("-", 40) . "\n"; //str_repeat gibt hier 40x "-" aus. } // Alphanumerischer Vergleich // Achtung, führt dazu, dass 10 < 4 gilt function cmp_pers($a, $b) { return strcmp($a[1],$b[1]); } // Numerischer Vergleich function cmp_pers_numeric($a, $b) { if ($a[1] - $b[1] == 0) { return strcmp($a[0],$b[0]); } else { return ($a[1] - $b[1]); } } print_array($array); sort($array); print_array($array); usort($array, "cmp_pers"); print_array($array); usort($array, "cmp_pers_numeric"); print_array($array);
<html> <head><title>Schleife</title></head> <body> <?php $zaehler = 0; while ($zaehler <= 10) { // while ($zaehler == 10) { ==> HINWEIS: Ausstieg bei exakt 10 // (wichtig!!: "==", da "=" eine Wertzuweisung bedeutet) echo "<p>Durchlauf $zaehler</p>"; $zaehler = $zaehler + 1; // Alternativen für's Hochzählen: // zaehler += 1; // zaehler++; } ?> </body> </html>
Alternativ zur WHILE-Schleife kennt PHP auch eine sogenannte fussgesteuerte Schleife (DO WHILE), bei der die Prüfung am Ende der Schleife steht.
//...Beispiel aus fotos.inc.php (siehe unten) do { $idx = rand(0, count($liste) - 1); } while ($idx == $_SESSION['select_one_lastidx']); //...
Die FOREACH-Schleife besonders gut für die Ausgabe von Arrays geeignet.
<html> <head> <title>Namensliste</title> <!-- Zeichensatz auf UTF8 für die Darstellung von Umlauten --> <meta charset="utf-8"> </head> <body> <?php $liste = array("Thomas", "Oliver", "Uli", "Jürgen"); ?> <ul> <?php foreach ($liste as $name) { echo "<li>$name</li>"; } ?> </body> </html>
Die erweiterte Form der FOREACH-Schleife unterstützt auch assoziative Arrays:
//... // $name => $anzahl stellt sowohl den Key als auch den Wert in einem assoziativen Array zur Verfügung foreach ($liste as $name => $anzahl) { //... }
Beispiel einfaches Array: (ohne HTML-Ausgabe)
<?php $liste = array(); $werte = array(2,4,6,8); // ab php Version 5.4 geht auch $werte2 = [1,2,3,4]; // count = Anzahl der Elemente echo "Anzahl der Elemente in \$liste: " . count($liste) . "\n"; echo "Anzahl der Elemente in \$werte: " . count($werte) . "\n"; // Zugriff auf einzelne Elemente: echo "1. Wert: " . $werte[0] . "\n"; // Ausgabe der Elemente mit einer WHILE-Schleife: echo "\nWHILE: Schleife \n"; $zaehler = 0; // .. Index beginnt bei Null, deshalb ist der höchste Index 1 kleiner als die Anzahl der Elemente. // .. Deshalb muss die Schleife mit "<" und nicht mit "<=" beendet werden. while ($zaehler < count($werte)) { echo "Wert: " . $werte[$zaehler] . "\n"; $zaehler++; }
Für die Arbeit mit Arrays gibt es verschiedene fertige Funktionen:
Neue Werte ans Ende anhängen
// ... $werte = array(2,4,6,8); // ... array_push($werte, 10); $werte[] = 12;
„count“ liefert die Anzahl der Werte in einem Arrays.
//... while ($zaehler < count($werte)) { echo "Wert: " . $werte[$zaehler] . "\n"; $zaehler++; //...
Mit „array_keys()“ kann man eine Liste der Indexwerte(Schlüsselworte) eines assoziativen Arrays erstellen.
//... printf("Alle Indexwerte: %s\n", implode(", ", array_keys($assoc))); //...
Diese kann z.B. dazu genutzt werden, bestimmte oder alle Werte eines Arrays auszugeben.
<html> <head> <title>Kursliste</title> <!-- Zeichensatz auf UTF8 für die Darstellung von Umlauten --> <meta charset="utf-8"> </head> <body> <?php // Initialisierung mit key-value-Paaren $liste = array('Perl' => 4, 'LPI1' => 6, 'Android' => 4); ?> <ul> <?php // array_keys() liefert eine Liste der Keys foreach (array_keys($liste) as $name) { $anzahl = $liste[$name]; echo "<li>$name: $anzahl Teilnehmer</li>"; } ?> </body> </html>
Liefert analog zu array_keys() in einem assoziativem Array die Werte des Arrays wieder.
//... printf("Alle Werte: %s\n", implode(", ", array_values($assoc))); //...
Array mit Trennzeichen ausgeben. Sehr hilfreiche für die kurzfristige Ausgabe eines Arrays (z.B. für DEBUG)
//... // Array-Funktion implode("TRENNZEICHEN", ARRAY) echo implode(", ", $liste[$name]); //...
Array anlegen aus einem String mit Trennzeichen durch „explode“ (streng genommen ist „explode“ natürlich eine String-Funktion).
<?php $namen = "Hans,Michael,Torsten,Toni,Klaus,Tom"; $liste = explode(",", $namen); foreach ($liste as $name) { echo $name . "\n"; }
Mit „unset()“ wird ein Element aus dem Array gelöscht. Damit kürzt sich zwar die Länge des Arrays (z.B. bei count($array)). Die Indexposition bleibt jedoch erhalten.
$array = array(1,2,3,4,5,6); printf("Länge vor unset: %d\n", count($array)); // Ausgabe: "Länge vor unset: 6" unset($array[3]); // Löscht die Indexposition 3 printf("Länge nach unset: %d\n", count($array)); // Ausgabe: "Länge vor unset: 5" printf("Element 3: %s\n", $array[3]); // liefert die Ausgabe "Element 3: "
Mit „array_splice“ kann in ein Array gekürzt oder erweitert werden. Dabei wird ab einer bestimmten Indexposition ein Array von Werten eingefügt oder durch ein leeres Array überschrieben (= gelöscht). Die nachfolgenden Werte im Array werden entsprechen auf bzw. nachgerückt.
array_splice($array, <Startposition>, <Anzahl zu ersetzenden Elemente>, array(>neue Werte>); // Beispiel: Ab Indexpos 3 wird 1 Element durch nichts (leeres Array) ersetzen array_splice($array, 3, 1, array());
Alle drei Funktionen bieten die Möglichkeit (auch komplexe) Arrays auszugeben.
<?php $data = array("ab", "cd", "ef"); print_r($data); var_dump($data); var_export($data); // liefert eine Ausgabe, die PHP-Code entspricht ~
<html> <head> <title>Kursliste</title> <!-- Zeichensatz auf UTF8 für die Darstellung von Umlauten --> <meta charset="utf-8"> </head> <body> <?php $liste = array(); $liste['PHP'] = 4; $liste['LPI1'] = 6; $liste['Android'] = 4; ?> <ul> <?php // $name => $anzahl stellt sowohl den Key als auch den Wert in einem assoziativen Array zur Verfügung foreach ($liste as $name => $anzahl) { echo "<li>$name: $anzahl Teilnehmer</li>"; } ?> </body> </html>
<html> <head> <title>Kursliste</title> <!-- Zeichensatz auf UTF8 für die Darstellung von Umlauten --> <meta charset="utf-8"> </head> <body> <?php // Initialisierung mit key-value-Paaren $liste = array('Perl' => array(), 'Python' => array()); $liste['PHP'] = array('Thomas', 'Oliver', 'Uli', 'Jürgen'); $liste['LPI1'] = array('Klaus', 'Toni', 'Anna', 'Arne', 'Mike', 'Tom'); $liste['Android'] = array('Theo', 'Hans', 'Michael', 'Carlo'); ?> <ul> <?php // array_keys() liefert eine Liste der Keys foreach (array_keys($liste) as $name) { $anzahl = count($liste[$name]); echo "<li>$name: $anzahl Teilnehmer: "; foreach ($liste[$name] as $index => $teilnehmer) { echo "$teilnehmer"; if ($index < $anzahl-1) { echo ", "; } }; } echo "</li>"; ?> </body> </html>
Text-Dateien können zeilenweise eingelesen werden. Dafür muss zunächst ein Filehandle auf die Datei geöffnet. Die Datei kann dann innerhalb einer Schleife ausgelesen werden. Das Dateiende wird dabei über eine Abfrage auf die nächste Zeile (liefert „false“, wenn keine mehr existiert) festgestellt.
// ... $path = "/etc/passwd"; $fh = fopen($path, "r"); // filehandle = fopen(<datei>, <modus>) while (($line = fgets($fh, 2048)) !== false) { // fgets liefert die nächste Zeile und "false", wenn es keine nächste Zeile mehr gibt. // 2048 ist dabei die Zeilenlänge (Anzahl der Zeichen) echo $line; } //...
Beispiel (Einlesen der Datei /etc/passwd in ein Array und formatierte Ausgabe):
<html> <head> <title>Userliste</title> <!-- Zeichensatz auf UTF8 für die Darstellung von Umlauten --> <meta charset="utf-8"> </head> <body> <?php $path = "/etc/passwd"; $userlist = array(); $fh = fopen($path, "r"); // filehandle = fopen(<datei>, <modus>) while (($line = fgets($fh, 2048)) !== false) { // fgets liefert die nächste Zeile und "false", wenn es keine nächste Zeile mehr gibt. // 2048 ist dabei die Zeilenlänge (Anzahl der Zeichen) $userlist[] = explode(":", $line); } // Ausführliche Formulierung: // $line = fgets($fh, 2048); // while ($line !== false) { // $line = fgets($fh, 2048); // } fclose($fh); //filehandle schließen ?> <table border=0> <?php foreach ($userlist as $userarray) { $row = "<tr>"; foreach ($userarray as $wert) { $row .= "<td>$wert</td>"; } $row .= "</tr>"; echo $row; } ?> </table> </body> </html>
Das ganze kann man auch etwas aufwendiger mit sortierbaren Überschriften gestalten.
<?php if (isset($_GET['col']) && is_numeric($_GET['col']) ) { //isset prüft, ob eine Variable gesetzt ist if ($_GET['col'] >= 0 && $_GET['col'] < 6) { //Validitätsprüfung, nur Spalten 0..5 erlaubt $sort_column = $_GET['col']; } else { echo "<H1>Finger weg von der URL!!!</H1>"; $sort_column = 0; } } else { $sort_column = 0; } ?> <html> <head> <title>Userliste</title> <!-- Zeichensatz auf UTF8 für die Darstellung von Umlauten --> <meta charset="utf-8"> <style> table.colored_table th { background: lightblue; } table.colored_table tr:nth-child(even) { background: lightgray; } table.colored_table tr:nth-child(odd) { background: white; } </style> </head> <body> <?php $path = "/etc/passwd"; $userlist = array(); $fh = fopen($path, "r"); // filehandle = fopen(<datei>, <modus>) while (($line = fgets($fh, 2048)) !== false) { // fgets liefert die nächste Zeile und "false", wenn es keine nächste Zeile mehr gibt. // 2048 ist dabei die Zeilenlänge (Anzahl der Zeichen) $userarray = explode(":", $line); array_splice($userarray, 1, 1, array()); //Passwort-"Spalte" löschen // Ans Ende des Arrays anhängen $userlist[] = $userarray; //$userlist[$userarray[$sort_column]] = $userarray; } // Ausführliche Formulierung: // $line = fgets($fh, 2048); // while ($line !== false) { // $line = fgets($fh, 2048); // } fclose($fh); //filehandle schließen echo "Sortierung nach Spalte " . $sort_column; ?> <table class="colored_table"> <tr> <th><a href="passwd.php?col=0">Login</th> <th><a href="passwd.php?col=1">UID</th> <th><a href="passwd.php?col=2">GID</th> <th><a href="passwd.php?col=3">Name</th> <th><a href="passwd.php?col=4">Home</th> <th><a href="passwd.php?col=5">Shell</th> <!-- mit "col=0" wird das Standard-Array _GET befüllt --> <?php function cmp_by_col($a, $b) { global $sort_column; //Global, wird oben gesetzt if ($sort_column == 1 || $sort_column == 2) { // UID || GID return $a[$sort_column] - $b[$sort_column]; } $a[$sort_column] = strtolower($a[$sort_column]); $b[$sort_column] = strtolower($b[$sort_column]); return strcmp($a[$sort_column],$b[$sort_column]); // return strcasecmp($a[$sort_column],$b[$sort_column]) } usort($userlist, "cmp_by_col"); //echo implode("#",$keys); foreach ($userlist as $userarray) { $row = "<tr>"; foreach ($userarray as $wert) { $row .= "<td>$wert</td>"; } $row .= "</tr>"; echo $row; } ?> </table> </body> </html>
Eigene Funktion:
//... <?php function print_data($daten) { echo "<pre>\n"; print_r($daten); echo "\n</pre>\n"; } //... <?php print_data($liste); //Aufruf der function (mit Übergabe der Daten $liste) //..
Funktionen können auch in eigene Dateien ausgelagert und mittels „include()“ bzw. „include_once()“ eingebunden werden.
<?php // Funktion print_data aus Include-Datei einbinden // Include-Dateien sollten keine eigene Ausgabe besitzen include_once("inc_debug.php"); ?>
<?php //function add10($wert) // Pflichtparameter function add10($wert=0) // optionaler Parameter { $wert += 10; return $wert; // liefert den Wert zurück } printf("%d\n", add10(10)); printf("%d\n", add10());
<?php $value = 12; function add_value($wert=0) { global $value; // Aus globalen Scope importieren $ergebnis = $wert + $value; return $ergebnis; } printf("%d\n", add_value(10));
Wendet eine Funktion auf alle Elemente eines Arrays an.
<?php function add10($wert=0) { $wert += 10; return $wert; // liefert den Wert zurück } $werte = array(3,4,5,6,7); $neu = array_map("add10", $werte); //wendet eine Funktion auf alle Elemente in einem Array an print_r($neu);
Sessions können dazu genutzt werden, Daten zu speichern und in anderen „Durchläufen“ des Programms wieder zu nutzen.
Die Session muss dabei vor den HTML-Header Informationen gestartet werden (es wird dabei ein Cookie erstellt).
Soll nicht der Default-Name „PHPSESSID“ für die Session benutzt werden, kann mit „session_name()“ ein benutzerdefinierter Name vergeben werden.
<?php session_name("PHPFOTOS"); // optionaler anderer Name stat PHPSESSID session_start(); ?> <html> <head> <title>...</title> <meta charset="utf-8"> </head>
Durch die Session wird ein Array „$_SESSION“ zur Verfügung gestellt, in dem die Informationen mit entsprechenden Keys hinterlegt und abgefragt werden können.
//... Beispiel aus fotos.inc.php $_SESSION['select_one_lastidx'] = -1; //... if ($idx == $_SESSION['select_one_lastidx']) { //... }
Inhalt der Session kann man sich mit einem kleiner Programm ansehen.
<?php session_start(); require_once("dienstag/inc_debug.php"); ?> <html> <head> <title>Session Dump</title> <meta charset="utf-8"> </head> <body> <h2>Session Dumper</h2> <?php print_data($_SESSION); ?> </body> </html>
<!-- ... --> <body> <h2><?=$titel?></h2> <!-- "Short-Opening Tag" dabei erwartet "=" eine Variable --> <?php #print_data($_POST); ?> <!-- method="GET => Daten landen in der URL-Zeile --> <!-- Die Daten können dann über die Super-Globals $_GET bzw. $_POST angesprochen werden --> <form action="formular.php" method="POST"> <input type="text" name="vorname"> <input type="submit" value="Anmelden"> </form>
<!-- ... --> <h3>Zahlen addieren</h3> <form action="formular.php" method="POST"> <input type="text" name="operand1" value="<?=$_POST['operand1']?>"> <select type="select" name="operator"> <option value="add" <?=$add_selected?>>+</option> <option value="sub" <?=$sub_selected?>>-</option> <option value="mul" <?=$mul_selected?>>*</option> <option value="div" <?=$div_selected?>>/</option> </select> <input type"text" name="operand2" value="<?=$_POST['operand2']?>"> <input type="submit" value="Berechne"> </form>
//... <BR> <input type="radio" name="wday" value="Montag">Montag <!-- Dienstag durch "checked" vorselektiert --> <input type="radio" name="wday" value="Dienstag" checked>Dienstag <input type="radio" name="wday" value="Mittwoch">Mittwoch <input type="radio" name="wday" value="Donnerstag">Donnerstag <input type="radio" name="wday" value="Freitag">Freitag <input type="radio" name="wday" value="Samstag">Samstag <input type="radio" name="wday" value="Sonntag">Sonntag </BR> //...
<input type="checkbox" name="cron" value="ja">per cron ausführen <br> <input type="checkbox" name="aktiv" value="ja">aktive Daten
Die Variablen mit dem Wert „ja“ werden nur übermittelt, wenn die checkbox ausgewählt wurde.
„textarea“ ist kein „input type“ sondern ein eigener Type. Die Größe des angezeigten Feldes (nicht des Inhaltes) kann mit „rows“ und „cols“ mitgegeben werden.
<textarea name="blabla" rows="10" cols="60">Hier kann ein Default-Text stehen </textarea>
Damit bietet der Browser eine Möglichkeit an, eine Datei ins BackEnd zu laden. Informationen zu der Hochgeladenen Datei werden dabei in der „Super_Global“ „$_FILES“ gespeichert. (enctype=„multipart/form-data“ wird dabei im form-tag benötigt)
<form action="fotos.php" method="POST" enctype="multipart/form-data"> <input type="file" name="foto"><br> <input type="submit" value="Hochladen">
Eingabefelder birgen das Risiko, dass auch ungewollte Inhalte eingegeben werden. z.B. weiterer HTML oder PHP-Code. Selbst Werte, die über „type=radio“ oder „type=select“ vordefiniert sind, können mit Browser Add-ons wie „tamper data“ verändert und ins BackEnd geschickt werden.
Das ist eine einfache Funktion, die spezielle HTML-Zeichen in „harmlose“ Zeichen bzw. in die HTML-Darstellung dieses Zeichens umwandelt.
'&' (Ampersand/kaufmännisches Und) wird zu '&'. '"' (doppeltes Anführungszeichen) wird zu '"', wenn ENT_NOQUOTES nicht gesetzt ist. "'" (einfaches Anführungszeichen) wird nur zu ''', wenn ENT_QUOTES gesetzt ist. '<' (kleiner als) wird zu '<' '>' (größer als) wird zu '>'
Bei Funktionen wie „print_r“ muss man etwas aufwendiger durch eine Zusatzfunktion erst die Zeichenkette (return true) zurückgeben, um diese z.B. durch htmlspecialchars umwandeln zu lassen.
<?php function print_data($daten) { echo "<pre>\n"; //print_r($daten); echo htmlspecialchars(print_r($daten, true)); echo "\n</pre>\n"; }
Mit Hilfe dieser Befehle kann eine Zeichenumwandlung auch selbst geschrieben werden.
//... $titel = "Formular"; // Namen mit < > & ausschließen if (isset($_POST['vorname']) && strlen($_POST['vorname']) && strpos($_POST['vorname'], '<') === false && strpos($_POST['vorname'], '>') === false && strpos($_POST['vorname'], '&') === false ) { // Gewisse Zeichen "unschädlich" machen $_POST['vorname'] = str_replace(['<', '>', '&'], ['','',''], $_POST['v..']); $_SESSION['vorname'] = htmlspecialchars($_POST['vorname']); } if (isset($_SESSION['vorname'])) { $titel = "Hallo " . $_SESSION['vorname']; } //...
Besser strukturiert wird das Programm aufgeteilt in einen Basis-Teil, die Funktionen und das CSS-File.
<?php require_once("passwd.inc.php"); //Einbinden der Datei mit Zusatzfunktionen if (isset($_GET['col']) && is_numeric($_GET['col']) ) { //isset prüft, ob eine Variable gesetzt ist if ($_GET['col'] >= 0 && $_GET['col'] < 6) { //Validitätsprüfung, nur Spalten 0..5 erlaubt $sort_column = $_GET['col']; } else { echo "<H1>Finger weg von der URL!!!</H1>"; $sort_column = 0; } } else { $sort_column = 0; } $path = "/etc/passwd"; $userlist = read_passwd($path); ?> <html> <head> <title>Userliste</title> <!-- Zeichensatz auf UTF8 für die Darstellung von Umlauten --> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href="passwd.css"> </head> <body> <p>Sortierung nach Spalte <?php echo $sort_column; ?></p> <table class="colored_table"> <tr> <th><a href="passwd.php?col=0">Login</th> <th><a href="passwd.php?col=1">UID</th> <th><a href="passwd.php?col=2">GID</th> <th><a href="passwd.php?col=3">Name</th> <th><a href="passwd.php?col=4">Home</th> <th><a href="passwd.php?col=5">Shell</th> <!-- mit "col=0" wird das Standard-Array _GET befüllt --> <?php usort($userlist, "cmp_by_col"); foreach ($userlist as $userarray) { $row = "<tr>"; foreach ($userarray as $wert) { $row .= "<td>$wert</td>"; } $row .= "</tr>"; echo $row; } ?> </table> </body> </html>
<?php /* * Include-Datei mit Zusatzfunktionen für passwd.php */ function read_passwd($path) { $userlist = array(); $fh = fopen($path, "r"); // filehandle = fopen(<datei>, <modus>) while (($line = fgets($fh, 2048)) !== false) { // fgets liefert die nächste Zeile und "false", wenn es keine nächste Zeile mehr gibt. // 2048 ist dabei die Zeilenlänge (Anzahl der Zeichen) $userarray = explode(":", $line); array_splice($userarray, 1, 1, array()); //Passwort-"Spalte" löschen // Ans Ende des Arrays anhängen $userlist[] = $userarray; } fclose($fh); //filehandle schließen return $userlist; //neues Array mit allen Daten zurückliefern } function cmp_by_col($a, $b) { global $sort_column; //Global, wird oben gesetzt if ($sort_column == 1 || $sort_column == 2) { // UID || GID return $a[$sort_column] - $b[$sort_column]; } $a[$sort_column] = strtolower($a[$sort_column]); $b[$sort_column] = strtolower($b[$sort_column]); return strcmp($a[$sort_column],$b[$sort_column]); // return strcasecmp($a[$sort_column],$b[$sort_column]) }
table.colored_table th { background: lightblue; } table.colored_table tr:nth-child(even) { background: lightgray; } /* das ist im CSS die einzig erlaubte Art, Kommentare zu schreibe */ table.colored_table tr:nth-child(odd) { background: white; }
Es werden Bilder aus einem Unterverzeichnis in zufälliger Reihenfolge angezeigt. Es wird dabei über eine SESSION-Variable sichergestellt, dass kein Bild zweimal hintereinander dargestellt wird.
Der Verzeichnisname wird in einer Config-Datei hinterlegt und als Konstante definiert. Die Darstellung wird über eine Style-Sheet-Datei formatiert.
Außerdem ist eine Upload-Funktion eingebaut - incl. Gültigkeitsprüfung des Dateinames.
<?php session_start(); require_once("fotos.conf.php"); require_once("fotos.inc.php"); require_once("dienstag/inc_debug.php"); $fotos = get_fotos(); $path = select_one($fotos); $upload_msg = store_foto(); if (strlen($upload_msg)) { // Kleiner Trick, damit ein Reload die POST-Daten nicht erneut schickt. $_SESSION['upload_msg'] = $upload_msg; header("Location: fotos.php"); // Redirect auf GET fotos.php exit(); // Verarbeitung beenden, Rest macht der Browser } ?> <html> <head> <title>Fotos</title> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href="fotos.css"> </head> <body> <?php #print_data($_POST); ?> <?php #print_data($_FILES); ?> <h2>Urlaubsfotos</h2> <?php if ($_SESSION['upload_msg']) echo "<p>".$_SESSION['upload_msg']."</p>"; $_SESSION['upload_msg'] = false; ?> <img src="<?php echo $path; ?>" /> <form action="fotos.php" method="POST" enctype="multipart/form-data"> <input type="file" name="foto"><br> <input type="submit" value="Hochladen"> </form> </body> </html>
<?php define('PICSDIR', 'bilder');
<?php function get_fotos() { if ($dir = opendir(PICSDIR)) { // Verwendung einer Konstanten, deshalb ohne " oder $ while (false !== ($file = readdir($dir))) { // if ($file != "." && $file != "..") // Prüfung, auf . bzw .. "Dateien" im Verzeichnis if (strtolower(substr($file, -4)) == ".jpg") $liste[] = $file; elseif (strtolower(substr($file, -5)) == ".jpeg") $liste[] = $file; // } } closedir($dir); } return $liste; } function select_one($liste) { // Einfacher Code, um sicherzustellen, dass ein alter Index existiert if (!isset($_SESSION['select_one_lastidx'])) $_SESSION['select_one_lastidx'] = -1; do { $idx = rand(0, count($liste) - 1); //rand bezieht min und max mit ein (deshalb count-1) } while ($idx == $_SESSION['select_one_lastidx']); // Neuberechnung, falls der Wert gleich dem alten ist error_log("alte Zufallszahl: " . $_SESSION['select_one_lastidx']); error_log("Zufallszahl: $idx"); //debug $_SESSION['select_one_lastidx'] = $idx; //Speichern der Zufallszahl in der SESSION Variable. return PICSDIR . "/" . $liste[$idx]; } function store_foto() { // Prüfung, ob ein Foto hochgeladen wurde, und der Upload erfolgreich war if (isset($_FILES['foto']) && $_FILES['foto']['error'] == 0) { $pathinfo = pathinfo($_FILES['foto']['name']); // Prüfung der Dateiendung auf Gültigkeit $pathinfo['extension'] = strtolower($pathinfo['extension']); if (!in_array($pathinfo['extension'], ['jpg','jpeg', 'tif', 'png', 'tiff'])) return 'Ungülteriger Dateiname!'; // \w Buchstabe (word char) // \d Ziffer (digit) // \. Punkt // _ Underscore // . Bindestrich // [^...] Ein Zeichen nicht aus der andgegebenen Gruppe //if (preg_match('/[^\w\d._-]/', $pathinfo['basename'])) // return 'Ungültige Zeichen im Dateinamen'; // Alternative: Alle ungültigen Zeichen Löschen: $pathinfo['filename'] = preg_replace('/([^\w\d._-])/', '', $pathinfo['filename']); $path = PICSDIR . '/' . $pathinfo['filename'] . '.' . $pathinfo['extension']; $nr = 1; while (file_exists($path)) { $nr++; $path = PICSDIR . '/' . $pathinfo['filename'] . '-' . $nr . '.' . $pathinfo['extension']; } // basename liefert den Dateinamen ohne Pfad (analog dirname) if (move_uploaded_file($_FILES['foto']['tmp_name'], $path)) return 'Neues Foto gespeichert'; else return 'Konte Foto nicht speichern'; } return ''; }
body { background-color:#99FF66; font-weight:bold; font-family:Arial; font-size:120%; } img {border-width:12px; border-color:#66CC66; border-style:ridge; padding:5px; } ~
<?php session_start(); //require_once("formular.conf.php"); require_once("formular.inc.php"); require_once("formular.conf.php"); require_once("dienstag/inc_debug.php"); $titel = "Formular"; if (isset($_POST['vorname']) && strlen($_POST['vorname'])) { $_SESSION['vorname'] = $_POST['vorname']; } if (isset($_SESSION['vorname'])) { $titel = "Hallo " . $_SESSION['vorname']; } ?> <html> <head> <title>Formular</title> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href="formular.css"> </head> <body> <h2><?=$titel?></h2> <!-- "Short-Opening Tag" dabei erwartet "=" eine Variable --> <?php print_data($_POST); ?> <!-- method="GET => Daten landen in der URL-Zeile --> <!-- Die Daten können dann über die Super-Globals $_GET bzw. $_POST angesprochen werden --> <form action="formular.php" method="POST"> <input type"text" name="vorname"> <input type="submit" value="Anmelden"> </form> <?php $ergebnis = false; $add_selected = ''; $sub_selected = ''; $mul_selected = ''; $div_selected = ''; if (isset($_POST['operand1']) && isset($_POST['operand2']) && is_numeric($_POST['operand1']) && is_numeric($_POST['operand2'])) { switch ($_POST['operator']) { case 'add': $ergebnis = $_POST['operand1'] + $_POST['operand2']; $add_selected = "selected"; break; case 'sub': $ergebnis = $_POST['operand1'] - $_POST['operand2']; $sub_selected = "selected"; break; case 'mul': $ergebnis = $_POST['operand1'] * $_POST['operand2']; $mul_selected = "selected"; break; case 'div': $ergebnis = $_POST['operand1'] / $_POST['operand2']; $div_selected = "selected"; break; } } ?> <h3>Zahlen addieren</h3> <form action="formular.php" method="POST"> <input type="text" name="operand1" value="<?=$_POST['operand1']?>"> <select type="select" name="operator"> <!-- Array $calc_operator wird in einer conf-Datei aufgebaut --> <?php echo form_options($calc_operator, $_POST['operator']) ?> </select> <input type"text" name="operand2" value="<?=$_POST['operand2']?>"> <input type="submit" value="Berechne"> </form> <?php if ($ergebnis !== false) echo "<p>Ergebnis der Berechung: $ergebnis</p>"; else echo "<p>Formular nicht korrekt ausgefüllt</p>"; ?> </body> </html>
<?php // assotiatives Array als Key-Value Paar $calc_operator = array('add' => '+', 'sub' => '-', 'mul' => '*', 'div' => '/'); /* // verschachteltes Array $calc_opterator = array(['add', '+'], ['sub', '-'], ['mul', '*'], ['div', '/'] ); */
<?php // erzeugt <option>s für Formular <select>-Elemente // $optarr = array der Optionen // Pro Option: Index 0 = value, Index 1 = angezeigter Text function form_options($optarr, $selected) { $html = ''; foreach ($optarr as $key => $option) { // Lösung mit Key-Value Paaren // foreach ($optarr as $option) { // Lösung für ein verschachteltes Array //$html .= '<option value="' . $option[0] . '" selected>' . $option[1] . '</option>'; // einfacher/lesbarer mit sprintf (liefert eine Zeichenkette zurück) /* if ($option[0] == $selected) $html .= sprintf('<option value="%s" selected>%s</option>', $option[0], $option[1]); else $html .= sprintf('<option value="%s">%s</option>', $option[0], $option[1]); */ // oder ganz kurz: sprintf mit "eingebautem" if // error_log("option = $option"); // DEBUG $html .= sprintf('<option value="%s"%s>%s</option>', $key, ($key == $selected) ? ' selected' : '', $option); } return $html; }
form:hover { border: 1px dashed #555; background: #DDD; }
Für die „Laden-Funktion“ wird „jquery-2.1.1.min.js“ genutzt. Diese kann von http://jquery.com/download/ heruntergeladen werden.
<?php // muss eine der ersten Anweisungen sein, vor allen Textausgaben session_name("PHPADDR"); // optionaler anderer Name statt PHPSESSID session_start(); // Session beginnen bzw. wiederverwenden require_once("adressen.conf.php"); require_once("adressen.inc.php"); require_once("Dienstag/inc_debug.php"); $db = dbconnect(); if (isset($_POST['ajax'])) { $data = array(); if (isset($_POST['load']) && is_numeric($_POST['load'])) { $data = fetch_address($db, $_POST['load']); } header('Content-type: application/json; charset="UTF-8"'); echo json_encode($data); exit(); } // besser vielleicht alle Felder zu pruefen if (isset($_POST['name']) && strlen($_POST['name'])) { // Rueckgabetext der Funktion in der Sesseion zwischenspeichern, // da das Programm gleich mit exit verlassen wird und beim // naechsten Aufruf via GET der Text sonst nicht mehr angezeigt // werden koennte if (isset($_GET['edit']) && is_numeric($_GET['edit'])) $_SESSION['new_address_msg'] = update_address($db, $_GET['edit']); else $_SESSION['new_address_msg'] = save_new_address($db); // POST-Daten sind verarbeitet, jetzt auf Seite mit GET-Request verweisen, // um beim RELOAD die POST-Daten *nicht* erneut zu schicken header("Location: adressen.php"); exit(); } elseif (isset($_GET['delete']) && is_numeric($_GET['delete'])) { $ret = delete_address($db, $_GET['delete']); } elseif (isset($_GET['edit']) && is_numeric($_GET['edit'])) { $editvalues = fetch_address($db, $_GET['edit']); } ?> <html> <head> <title>Adressen</title> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href="adressen.css"> <script type="text/javascript" src="jquery-2.1.1.min.js"></script> <script type="text/javascript" src="adressen.js"></script> </head> <body> <?php /* Datenbank-Zugriffe sind objekt-orientiert * query und fetch sind Funktionen von speziellen Objekten und * koennen nur ueber diese aufgerufen werden. * $db haelt die Verbindung zur Datenbank * $db->query() fuehrt ueber diese Verbindung das Statement aus * * $sth->fetch() liefert analog dazu zum vorher ausgefuehrten Statement * jeweils eine Zeile des Ergebnisses * * Schreibweise ist an der Stelle immer OBJEKT -> FUNKTION * */ $sql = "SELECT count(*) FROM adressen"; $sth = $db->query($sql); $row = $sth->fetch(); ?> <h2>Adress-Datenbank mit <?php echo $row[0]; ?> Einträgen</h2> <?php $sql = "SELECT * FROM adressen"; $sth = $db->query($sql); ?> <table> <thead> <tr> <th>Nr.</th> <th>Name</th> <th>Strasse</th> <th>PLZ</th> <th>Ort</th> <th>Edit</th> <th>Del</th> <th class="nojshidden" style="display:none;">Load</th> </tr> </thead> <tbody> <?php // Der eingebettete HTML-Block wird in jedem Schleifendurchlauf // ausgefuehrt und entsprechend haeufig in die Ausgabe dupliziert while ($row = $sth->fetch()) { ?> <tr> <td><?php echo $row[0]; ?></td> <td><?php echo $row[1]; ?></td> <td><?php echo $row[2]; ?></td> <td><?php echo $row[3]; ?></td> <td><?php echo $row[4]; ?></td> <td><a href="adressen.php?edit=<?php echo $row[0]; ?>">bearbeiten</a></td> <td><a href="adressen.php?delete=<?php echo $row[0]; ?>">löschen</a></td> <td class="nojshidden" style="display:none"><a href="#" onclick="load_address(<?php echo $row[0]; ?>);return false">laden</a></td> </tr> <?php } ?> </tbody> </table> <h3>Neuen Eintrag aufnehmen</h3> <?php if (isset($_SESSION['new_address_msg']) && strlen($_SESSION['new_address_msg'])) { printf('<div class="message">%s</div>', $_SESSION['new_address_msg']); $_SESSION['new_address_msg'] = ''; ?> <script type="text/javascript"> window.setTimeout(function(){ // Alle div-Elemente der Klasse message verstecken $('div.message').hide(); }, 10000); </script> <?php } ?> <?php if (isset($_GET['edit']) && is_numeric($_GET['edit'])) { $url = sprintf('adressen.php?edit=%d', $_GET['edit']); } else { $url = 'adressen.php'; } ?> <form action="<?=$url?>" method="POST"> <?php // Alternative zur URL: if (isset($_GET['edit']) && is_numeric($_GET['edit'])) { ?> <input type="hidden" name="edit" value="<?=$_GET['edit']?>"> <?php } ?> Name: <input type="text" name="name" size="60" value="<?=$editvalues['name']?>"><br> Strasse: <input type="text" name="strasse" size="60" value="<?=$editvalues['strasse']?>"><br> PLZ: <input type="text" name="plz" size="4" value="<?=$editvalues['plz']?>"><br> Ort: <input type="text" name="ort" size="60" value="<?=$editvalues['ort']?>"><br> <input type="submit" value="Eintragen"> <input type="reset"> </form> <div id="myform" style="display: none"> Hier wird ein Formular angezeigt. </div> </body> </html>
function load_address(id) { $.post('adressen.php', 'ajax=1&load=' + id, function(data){ // Hier werden die Daten verarbeitet $('input[name="name"]').val(data.name); $('input[name="strasse"]').val(data.strasse); $('input[name="plz"]').val(data.plz); $('input[name="ort"]').val(data.ort); }); } // Startcode: $(function(){ // Alle Elemente mit Klasse nojshidden anzeigen $('.nojshidden').show(); });
<?php function dbconnect() { // data-source-name $dsn = sprintf('%s:host=%s;dbname=%s', DBDRIVER, DBHOST, DBNAME); error_log("Connect with " . $dsn); $db = new PDO($dsn, DBUSER, DBPASS); return $db; } // name Buchstaben, Leerzeichen, Bindestrich // strasse Buchstaben, Leerzeichen, Bindestrich, Punkt, Ziffern, Apostroph // plz Ganzzahl, fuenf Ziffern // ort Buchstaben, Leerzeichen, Bindestrich, Slash, Klammern function check_address() { if (preg_match('/[^\w\- ]/u', $_POST['name'])) return 'Ungueltiges Zeichen im Namen'; if (preg_match('/[^\w\- \.\d\']/u', $_POST['strasse'])) return 'Ungueltiges Zeichen in der Strasse'; if (preg_match('/[^\w\- \/\(\)]/u', $_POST['ort'])) return 'Ungueltiges Zeichen im Ort'; if (!preg_match('/^\d{5}$/', $_POST['plz'])) return 'Ungueltige Postleitzahl'; return ''; } function save_new_address($db) { $check = check_address(); if (strlen($check)) return $check; // $db->quote() sorgt fuer sichere Kodierung von stoerenden Zeichen fuer SQL // frueher: mysql_real_escape_string // Bonus: Ergebnis ist immer in einfache Hochkommas eingefasst $sql = sprintf("INSERT INTO adressen (name,strasse,plz,ort) " . "VALUES (%s,%s,%s,%s)", $db->quote($_POST['name']), $db->quote($_POST['strasse']), $db->quote($_POST['plz']), $db->quote($_POST['ort'])); error_log($sql); // Kontrollausgabe if ($db->query($sql) === false) return 'Adresse konnte nicht in der Datenbank gespeichert werden'; return 'Alles gut, Adresse gespeichert.'; } function delete_address($db, $id) { $sql = sprintf("DELETE FROM adressen WHERE id = %d", $id); error_log($sql); // Kontrollausgabe #$db->query($sql); return "Adresse gelöscht"; } function fetch_address($db, $id) { $sql = sprintf("SELECT * FROM adressen WHERE id = %d", $id); error_log($sql); // Kontrollausgabe $sth = $db->query($sql); return $sth->fetch(); } function update_address($db, $id) { $check = check_address(); if (strlen($check)) return $check; $sql = sprintf("UPDATE adressen SET " . "name = %s, strasse = %s, plz = %s, ort = %s " . "WHERE id = %d", $db->quote($_POST['name']), $db->quote($_POST['strasse']), $db->quote($_POST['plz']), $db->quote($_POST['ort']), $id); error_log($sql); // Kontrollausgabe $db->query($sql); return 'Aktualisieren der Adresse war wohl erfolgreich'; }
<?php define('DBDRIVER', 'mysql'); define('DBHOST', 'DB-hostname'); define('DBUSER', 'DB-user'); define('DBPASS', 'DB-password'); define('DBNAME', 'DB-Name');
div.message { margin-bottom: 5px; border: 1px solid #555; background: #eee; } div#myform { width: 800px; height: 200px; position: absolute; top: 30px; left: 100px; z-index: 10; border: 1px solid #555; background: #eef; }