Benutzer-Werkzeuge

Webseiten-Werkzeuge


php_schulung_linuxhotel

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

php_schulung_linuxhotel [2015/05/28 22:05] (aktuell)
admin angelegt
Zeile 1: Zeile 1:
 +====== PHP Schulung Linuxhotel (Notizen) ======
 +====== Grundlagen ======
 +Nur Syntax-Check,​ keine Ausführung des Programms
 +<code php>
 +php -l test.php
 +</​code>​
  
 +Verbindung/​Addition von String-Variablen werden durch den "​."​ dargestellt. ​
 +Beispiele:
 +<code php>
 +$titel = $titel . ", hallo Essen"; ​
 +# oder
 +$titel .= ", hallo Essen";​
 +# oder
 +$titel = $basistitel . ", " . $spezialtitel;​
 +# oder
 + echo "<​h1>"​.$titel."</​h1>";​
 +</​code>​
 +===== Ausgaben =====
 +Ausgaben können mit dem Befehl "​echo"​ oder etwas eleganter mit dem Befehl "​printf"​ erzeugt werden.
 +<code php>
 +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
 +</​code>​
 +
 +<code php>
 +<?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);
 +
 +</​code>​
 +===== Hochkommata ======
 +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).
 +
 +===== Klammern =====
 +Geschweifte Klammern können genutzt werden, um das Ende einer Variablen zu definieren.
 +<code php>
 +//...
 +$op2 = "​2";​
 +$wert = "​{$op2}2";​ // $wert hat damit den Wert "​22"​
 +//​Alternativ könnte geschrieben werden
 +$wert = "​$op2"​ . "​2";​
 +/...
 +</​code>​
 +===== Berechnungen =====
 +
 +Berechnung innerhalb einer echo-Anweisung. Wichtig sind dabei die runden Klammern.
 +<code php>
 +#...
 +  echo "<​p>​Addition:​ " . ($wert1 + $wert2) . "</​p>";​
 +#...
 +</​code>​
 +
 +Berechnung mit Zuweisung zu einer neuen Variablen:
 +<code php>
 +#...
 +  $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.
 +#...
 +</​code>​
 +
 +===== error_log() =====
 +Mit der Funktion "​error_log()"​ kann direkt ins Apache-Error-Log geschrieben werden. Dies wird in erster Linie für Debug-Informationen genutzt.
 +<code php>
 +//...
 +error_log("​belieber Text oder Variablen"​);​
 +//...
 +</​code>​
 +====== Zahl Funktionen ======
 +===== octdec(), hexdec(), dechex() und decoct() =====
 +Zur Umwandlung zwischen den verschiedenen Zahlensystemen. ​
 +  * octdec() = Oktal -> Integer
 +  * hexdec() = Hexadezimal -> Interger
 +  * dechex() = Integer -> Hexadezimal
 +  * decoct() = Integer -> Oktal
 +
 +<code php>
 +<?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"
 +</​code>​
 +
 +===== round(), integer-Division und modulo-Operator =====
 +<code php>
 +<?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"
 +</​code>​
 +
 +Praktisches Beispiel für den modulo-Operator:​ "Es sollen nur gerade Zahlen ausgegeben werden"​
 +<code php>
 +<?php
 +
 +$zahl = 0;
 +
 +while ($zahl <= 15) {
 +  // Alle geraden Zahlen ausgeben, ungerade überspringen
 +  if ($zahl % 2 == 0) {  //modulo Operator
 +    echo $zahl . "​\n";​
 +  }
 +  $zahl++;
 +}
 +</​code>​
 +
 +======String Funktionen======
 +===== strlen() =====
 +"​strlen()"​ liefert die Länge eines Strings zurück.
 +<code php>
 +<?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"
 +</​code>​
 +
 +===== substr () =====
 +Mit "​substr"​ kann ein Teil einer Zeichenkette ausgegeben werden. Dabei werden als Parameter der String (oder Variable), das Startzeichen und die Länge mitgegeben.
 +
 +<code php>
 +//...
 +<?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));
 +//...
 +</​code>​
 +
 +Das kann auch mit anderen Stringfunktionen wie "​strlen"​ kombiniert werden. "​strlen"​ liefert dabei in diesem Beispiel die Länge des Strings (minus 2).
 +<code php>
 +// ...
 +// 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);
 +// ...
 +</​code>​
 +
 +===== trim, ltrim und rtrim =====
 +Mit den "​trim"​-Befehlen werden führende oder schließende Whitespaces (Leerzeichen) entfernt.
 +<code php>
 +<?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'
 +</​code>​
 +
 +===== str_replace() =====
 +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.
 +<code php>
 +$text = "ab cd";
 +$text = str_replace("​ ", "​_",​ $text);
 +printf("'​%s'​\n",​ $text); ​
 +// --> Ausgabe
 +// '​ab_cd'​
 +</​code>​
 +Sollen mehrere Zeichen ersetzt werden, kann auch innerhalb von str_replace mit Arrays gearbeitet werden.
 +<code php>
 +$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-'​
 +</​code>​
 +
 +===== strtoupper(),​ strtolower() und ucfirst(), lcfirst() =====
 +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.
 +
 +<code php>
 +$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
 +</​code>​
 +
 +====== String Vergleiche / Sortierung =======
 +<code php>
 +<?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));
 +</​code>​
 +
 +===== usort =====
 +Sortiert ein Array auf Grund einer benutzerdefinierten Vergleichfunktion. Bei der Sortierung ist man dabei vollkommen frei.
 +<code php>
 +<?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));
 +</​code>​
 +
 +Weiteres Beispiel:
 +<code php>
 +<?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);​
 +
 +</​code>​
 +====== Schleifen ======
 +
 +===== WHILE-Schleife =====
 +<code php while-schleife.php>​
 +<​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>​
 +</​code>​
 +
 +===== DO WHILE-Schleife =====
 +Alternativ zur WHILE-Schleife kennt PHP auch eine sogenannte fussgesteuerte Schleife (DO WHILE), bei der die Prüfung am Ende der Schleife steht.
 +<code php>
 +//​...Beispiel aus fotos.inc.php (siehe unten)
 +  do {
 +    $idx = rand(0, count($liste) - 1); 
 +  } while ($idx == $_SESSION['​select_one_lastidx'​]); ​
 +//...
 +</​code>​
 +
 +===== FOREACH-Schleife =====
 +Die FOREACH-Schleife besonders gut für die Ausgabe von Arrays geeignet.
 +<code php>
 +<​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>​
 +
 +</​code>​
 +
 +Die erweiterte Form der FOREACH-Schleife unterstützt auch assoziative Arrays:
 +<code php>
 +//...
 +// $name => $anzahl stellt sowohl den Key als auch den Wert in einem assoziativen Array zur Verfügung
 +foreach ($liste as $name => $anzahl) {
 +//...
 +}
 +</​code>​
 +====== Arrays ======
 +Beispiel einfaches Array: (ohne HTML-Ausgabe)
 +<code php array.php>​
 +<?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++;
 +}
 +
 +</​code>​
 +
 +===== Array Funktionen =====
 +Für die Arbeit mit Arrays gibt es verschiedene fertige Funktionen:
 +==== Array erweitern ====
 +
 +Neue Werte ans Ende anhängen
 +<code php>
 +// ...
 +$werte = array(2,​4,​6,​8);​
 +// ...
 +array_push($werte,​ 10);
 +$werte[] = 12;
 +</​code>​
 +
 +==== count() ====
 +"​count"​ liefert die Anzahl der Werte in einem Arrays.
 +<code php>
 +//...
 +while ($zaehler < count($werte)) {
 +  echo "Wert: " . $werte[$zaehler] . "​\n";​
 +  $zaehler++;
 +//...
 +</​code>​
 +
 +==== array_keys() ====
 +Mit "​array_keys()"​ kann man eine Liste der Indexwerte(Schlüsselworte) eines assoziativen Arrays erstellen.
 +<code php>
 +//...
 +printf("​Alle Indexwerte: %s\n", implode(",​ ", array_keys($assoc)));​
 +//...
 +</​code>​
 +Diese kann z.B. dazu genutzt werden, bestimmte oder alle Werte eines Arrays auszugeben.
 +<code php>
 +<​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>​
 +</​code>​
 +
 +==== array_values() ====
 +Liefert analog zu array_keys() in einem assoziativem Array die Werte des Arrays wieder.
 +<code php>
 +//...
 +printf("​Alle Werte: %s\n", implode(",​ ", array_values($assoc)));​
 +//...
 +</​code>​
 +==== implode ====
 +Array mit Trennzeichen ausgeben. Sehr hilfreiche für die kurzfristige Ausgabe eines Arrays (z.B. für DEBUG)
 +<code php>
 +//...
 +// Array-Funktion implode("​TRENNZEICHEN",​ ARRAY)
 +echo implode(",​ ", $liste[$name]);​
 +//...
 +</​code>​
 +
 +==== explode ====
 +Array anlegen aus einem String mit Trennzeichen durch "​explode"​ (streng genommen ist "​explode"​ natürlich eine String-Funktion). ​
 +<code php>
 +<?php
 +$namen = "​Hans,​Michael,​Torsten,​Toni,​Klaus,​Tom";​
 +$liste = explode(",",​ $namen);
 +foreach ($liste as $name) {
 +  echo $name . "​\n";​
 +}
 +</​code>​
 +
 +==== unset() ====
 +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.
 +<code php>
 +$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: "
 +</​code>​
 +
 +====array_splice()====
 +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.
 +<code php>
 +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());
 +</​code>​
 +
 +====sort()====
 +Sortiert ein Array
 +<code php>
 +sort($array);​
 +printf("​[%s]\n",​ implode(",",​ $array));
 +</​code>​
 +
 +====print_r(),​var_dump(),​var_export()====
 +Alle drei Funktionen bieten die Möglichkeit (auch komplexe) Arrays auszugeben.
 +
 +<code php>
 +<?php
 +
 +$data = array("​ab",​ "​cd",​ "​ef"​);​
 +
 +print_r($data);​
 +var_dump($data);​
 +var_export($data);​ // liefert eine Ausgabe, die PHP-Code entspricht
 +~                                                      ​
 +</​code>​
 + 
 +===== assoziative Arrays ======
 +
 +<code php assoziative_array.php>​
 +<​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>​
 +</​code>​
 +
 +
 +
 +===== Mehrdimensionale (verschachtelte) Arrays =====
 +<code php>
 +<​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>​
 +</​code>​
 +
 +====== Dateiverarbeitung (zeilenweise) =====
 +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.
 +<code php>
 +// ...
 +$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;
 +  }
 +//...
 +</​code>  ​
 +
 +Beispiel (Einlesen der Datei /etc/passwd in ein Array und formatierte Ausgabe):
 +<code php passwd.php>​
 +<​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>​
 +</​code>​
 +
 +===== Beispiel passwd_enhanced.php ====
 +
 +Das ganze kann man auch etwas aufwendiger mit sortierbaren Überschriften gestalten.
 +<code php passwd_enhanced.php>​
 +<?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>​
 +
 +</​code>​
 +
 +
 +====== function / include ======
 +Eigene Funktion:
 +<code php>
 +//...
 +<?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)
 +//..
 +</​code>​
 +
 +Funktionen können auch in eigene Dateien ausgelagert und mittels "​include()"​ bzw. "​include_once()"​ eingebunden werden.
 +<code php>
 +<?php
 +  // Funktion print_data aus Include-Datei einbinden
 +  // Include-Dateien sollten keine eigene Ausgabe besitzen
 +  include_once("​inc_debug.php"​);​
 +?>
 +</​code>​
 +
 +===== Parameter-Übergabe =====
 +<code 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());
 +
 +</​code>​
 +
 +===== Globale Variablen =====
 +<code php>
 +<?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));​
 +</​code>​
 +
 +===== array_map() =====
 +Wendet eine Funktion auf alle Elemente eines Arrays an.
 +<code php>
 +<?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);​
 +
 +</​code>​
 +====== Session ======
 +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.
 +<code php>
 +<?php
 +  session_name("​PHPFOTOS"​); ​ // optionaler anderer Name stat PHPSESSID
 +  session_start();​
 +?>
 +<​html>​
 +<​head>​
 +<​title>​...</​title>​
 +<meta charset="​utf-8">  ​
 +</​head>​
 +</​code>​
 +
 +Durch die Session wird ein Array "​$_SESSION"​ zur Verfügung gestellt, in dem die Informationen mit entsprechenden Keys hinterlegt und abgefragt werden können.
 +<code php>
 +//... Beispiel aus fotos.inc.php
 +$_SESSION['​select_one_lastidx'​] = -1;
 +//...
 +if ($idx == $_SESSION['​select_one_lastidx'​])
 +  {
 +  //...
 +  }
 +</​code>​
 +
 +Inhalt der Session kann man sich mit einem kleiner Programm ansehen.
 +<code php session_dumper.php>​
 +<?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>​
 +
 +</​code>​
 +====== Formulare ======
 +===== type="​text"​ =====
 +<code 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>​
 +</​code>​
 +
 +===== type="​select"​ =====
 +<code html>
 +<!-- ... -->
 +<​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>​
 +</​code>​
 +
 +===== type=radio =====
 +<code html>
 +//...
 +<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>
 +//...
 +</​code>​
 +
 +===== type=checkbox ======
 +<code html>
 +<input type="​checkbox"​ name="​cron"​ value="​ja">​per cron ausführen
 +<br>
 +<input type="​checkbox"​ name="​aktiv"​ value="​ja">​aktive Daten
 +</​code>​
 +Die Variablen mit dem Wert "​ja"​ werden nur übermittelt,​ wenn die checkbox ausgewählt wurde.
 +
 +===== textarea =====
 +"​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.
 +<code html>
 +<​textarea name="​blabla"​ rows="​10"​ cols="​60">​Hier kann ein Default-Text stehen
 +</​textarea>​
 +
 +</​code>​
 +
 +===== type=file =====
 +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)
 +<code html>
 +<form action="​fotos.php"​ method="​POST"​ enctype="​multipart/​form-data">​
 +<input type="​file"​ name="​foto"><​br>​
 +<input type="​submit"​ value="​Hochladen">​
 +</​code>​
 +
 +====== Eingaben prüfen|umwandeln ======
 +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.
 +
 +
 +===== htmlspecialchars() =====
 +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 '&​amp;'​.
 +    '"'​ (doppeltes Anführungszeichen) wird zu '&​quot;',​ wenn ENT_NOQUOTES nicht gesetzt ist.
 +    "'"​ (einfaches Anführungszeichen) wird nur zu '&#​039;',​ wenn ENT_QUOTES gesetzt ist.
 +    '<'​ (kleiner als) wird zu '&​lt;'​
 +    '>'​ (größer als) wird zu '&​gt;'​
 +
 +
 +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.
 +<code php>
 +<?php
 +  function print_data($daten)
 +  {
 +  echo "<​pre>​\n";​
 +  //​print_r($daten);​
 +  echo htmlspecialchars(print_r($daten,​ true));
 +  echo "​\n</​pre>​\n";​
 +  }
 +
 +</​code>​
 +
 +===== strpos() oder str_replace() =====
 +Mit Hilfe dieser Befehle kann eine Zeichenumwandlung auch selbst geschrieben werden.
 +<code php>
 +//...
 +  $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'​];​
 +  }
 +//...
 +</​code>​
 +====== Datenbankzugriff ======
 +
 +====== Beispiele ======
 +===== passwd.php - strukturiert ====
 +Besser strukturiert wird das Programm aufgeteilt in einen Basis-Teil, die Funktionen und das CSS-File.
 +<code php passwd.php>​
 +<?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>​
 +
 +</​code>​
 +
 +<code php passwd.inc.php>​
 +<?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])
 +}
 +
 +</​code>​
 +
 +<code css passwd.css>​
 +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;
 +}
 +
 +</​code>​
 +===== Bilder anzeigen =====
 +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.
 +<code php fotos.php>​
 +<?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>​
 +
 +</​code>​
 +
 +<code php fotos.conf.php>​
 +<?php
 +define('​PICSDIR',​ '​bilder'​);​
 +
 +</​code>​
 +
 +<code php fotos.inc.php>​
 +<?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 '';​
 +}
 +
 +</​code>​
 +
 +<code css fotos.css>​
 +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;​ }
 +~                                                                                        ​
 +</​code>​
 +
 +===== Formulare mit function =====
 +<code php formular.php>​
 +<?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>​
 +
 +</​code>​
 +
 +<code php formular.conf.php>​
 +<?php
 +// assotiatives Array als Key-Value Paar
 +$calc_operator = array('​add'​ => '​+',​
 +                       '​sub'​ => '​-',​
 +                       '​mul'​ => '​*',​
 +                       '​div'​ => '/'​);​
 +
 +/*
 +// verschachteltes Array
 +$calc_opterator = array(['​add',​ '​+'​],​
 +                        ['​sub',​ '​-'​],​
 +                        ['​mul',​ '​*'​],​
 +                        ['​div',​ '/'​]
 +                       );
 +*/
 +
 +</​code>​
 +
 +<code php formular.inc.php>​
 +<?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;
 +}
 +
 +</​code>​
 +
 +<code css formular.css>​
 +form:hover {
 +  border: 1px dashed #555;
 +  background: #DDD;
 +}
 +</​code>​
 +
 +===== Datenbankzugriff (und ein bisschen Javascript) =====
 +Für die "​Laden-Funktion"​ wird "​jquery-2.1.1.min.js"​ genutzt. Diese kann von http://​jquery.com/​download/​ heruntergeladen werden.
 +<code php adressen.php>​
 +<?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>​
 +</​code>​
 +
 +<code javascript adressen.js>​
 +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();​
 +});
 +</​code>​
 +
 +
 +<code php adressen.inc.php>​
 +<?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';​
 +}
 +</​code>​
 +
 +<code php adressen.conf.php>​
 +<?php
 +
 +define('​DBDRIVER',​ '​mysql'​);​
 +define('​DBHOST',​ '​DB-hostname'​);​
 +define('​DBUSER',​ '​DB-user'​);​
 +define('​DBPASS',​ '​DB-password'​);​
 +define('​DBNAME',​ '​DB-Name'​);​
 +
 +</​code>​
 +
 +<code css addressen.css>​
 +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;
 +}
 +
 +</​code>​
php_schulung_linuxhotel.txt · Zuletzt geändert: 2015/05/28 22:05 von admin