Benutzer-Werkzeuge

Webseiten-Werkzeuge


php_schulung_linuxhotel

PHP Schulung Linuxhotel (Notizen)

Grundlagen

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

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);

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.

//...
$op2 = "2";
$wert = "{$op2}2"; // $wert hat damit den Wert "22"
//Alternativ könnte geschrieben werden
$wert = "$op2" . "2";
/...

Berechnungen

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.
#...

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.

//...
error_log("belieber Text oder Variablen");
//...

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
<?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"

round(), integer-Division und modulo-Operator

<?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++;
}

String Funktionen

strlen()

„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"

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.

//...
<?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);
// ...

trim, ltrim und rtrim

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'

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.

$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-'

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.

$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

String Vergleiche / Sortierung

<?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));

usort

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);

Schleifen

WHILE-Schleife

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>

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.

//...Beispiel aus fotos.inc.php (siehe unten)
  do {
    $idx = rand(0, count($liste) - 1); 
  } while ($idx == $_SESSION['select_one_lastidx']); 
//...

FOREACH-Schleife

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) {
//...
}

Arrays

Beispiel einfaches Array: (ohne HTML-Ausgabe)

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++;
}

Array Funktionen

Für die Arbeit mit Arrays gibt es verschiedene fertige Funktionen:

Array erweitern

Neue Werte ans Ende anhängen

// ...
$werte = array(2,4,6,8);
// ...
array_push($werte, 10);
$werte[] = 12;

count()

„count“ liefert die Anzahl der Werte in einem Arrays.

//...
while ($zaehler < count($werte)) {
  echo "Wert: " . $werte[$zaehler] . "\n";
  $zaehler++;
//...

array_keys()

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>

array_values()

Liefert analog zu array_keys() in einem assoziativem Array die Werte des Arrays wieder.

//...
printf("Alle Werte: %s\n", implode(", ", array_values($assoc)));
//...

implode

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]);
//...

explode

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";
}

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.

$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: "

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.

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());

sort()

Sortiert ein Array

sort($array);
printf("[%s]\n", implode(",", $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
~                                                      

assoziative Arrays

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>

Mehrdimensionale (verschachtelte) Arrays

<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>

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.

// ...
$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):

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>

Beispiel passwd_enhanced.php

Das ganze kann man auch etwas aufwendiger mit sortierbaren Überschriften gestalten.

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>

function / include

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");
?>

Parameter-Übergabe

<?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());

Globale Variablen

<?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));

array_map()

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);

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.

<?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.

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>

Formulare

type="text"

<!-- ... -->
<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>

type="select"

<!-- ... -->
<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>

type=radio

//...
<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>
//...

type=checkbox

<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

„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>

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)

<form action="fotos.php" method="POST" enctype="multipart/form-data">
<input type="file" name="foto"><br>
<input type="submit" value="Hochladen">

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.

<?php
  function print_data($daten)
  {
  echo "<pre>\n";
  //print_r($daten);
  echo htmlspecialchars(print_r($daten, true));
  echo "\n</pre>\n";
  }

strpos() oder str_replace()

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'];
  }
//...

Datenbankzugriff

Beispiele

passwd.php - strukturiert

Besser strukturiert wird das Programm aufgeteilt in einen Basis-Teil, die Funktionen und das CSS-File.

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>
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])
}
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;
}

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.

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>
fotos.conf.php
<?php
define('PICSDIR', 'bilder');
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 '';
}
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; }
~                                                                                        

Formulare mit function

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>
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', '/']
                       );
*/
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;
}
formular.css
form:hover {
  border: 1px dashed #555;
  background: #DDD;
}

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.

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>
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();
});
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';
}
adressen.conf.php
<?php
 
define('DBDRIVER', 'mysql');
define('DBHOST', 'DB-hostname');
define('DBUSER', 'DB-user');
define('DBPASS', 'DB-password');
define('DBNAME', 'DB-Name');
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;
}
php_schulung_linuxhotel.txt · Zuletzt geändert: 2015/05/28 22:05 von admin