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

".$titel."

";
===== Ausgaben ===== Ausgaben können mit dem Befehl "echo" oder etwas eleganter mit dem Befehl "printf" erzeugt werden. echo "

Ausgabe Wert: " . $wert1 . "

"; // printf("

Ausgabe Wert: %d

", $wert1); printf("

Ausgabe Wert: %s

", $wert1); // %d = Int (Dezimal) // %s = String // %c = Char // %h = Hexadezimal // %o = Oktal
===== 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 "

Addition: " . ($wert1 + $wert2) . "

"; #...
Berechnung mit Zuweisung zu einer neuen Variablen: #... $ergebnis = $wert1 - $wert2; echo "

Substraktion: {$ergebnis}

"; # 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 ===== round(), integer-Division und modulo-Operator ===== Praktisches Beispiel für den modulo-Operator: "Es sollen nur gerade Zahlen ausgegeben werden" ======String Funktionen====== ===== strlen() ===== "strlen()" liefert die Länge eines Strings zurück. ===== 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. //... 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. 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 ======= %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. Weiteres Beispiel: ====== Schleifen ====== ===== WHILE-Schleife ===== Schleife HINWEIS: Ausstieg bei exakt 10 // (wichtig!!: "==", da "=" eine Wertzuweisung bedeutet) echo "

Durchlauf $zaehler

"; $zaehler = $zaehler + 1; // Alternativen für's Hochzählen: // zaehler += 1; // zaehler++; } ?>
===== 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. Namensliste
    $name"; } ?> 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 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. Kursliste 4, 'LPI1' => 6, 'Android' => 4); ?>
      $name: $anzahl Teilnehmer"; } ?> ==== 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). ==== 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, , , 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)); ====print_r(),var_dump(),var_export()==== Alle drei Funktionen bieten die Möglichkeit (auch komplexe) Arrays auszugeben. ===== assoziative Arrays ====== Kursliste
        $anzahl stellt sowohl den Key als auch den Wert in einem assoziativen Array zur Verfügung foreach ($liste as $name => $anzahl) { echo "
      • $name: $anzahl Teilnehmer
      • "; } ?>
        ===== Mehrdimensionale (verschachtelte) Arrays ===== Kursliste 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'); ?>
          $name: $anzahl Teilnehmer: "; foreach ($liste[$name] as $index => $teilnehmer) { echo "$teilnehmer"; if ($index < $anzahl-1) { echo ", "; } }; } echo ""; ?> ====== 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(, ) 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): Userliste , ) 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 ?> "; foreach ($userarray as $wert) { $row .= ""; } $row .= ""; echo $row; } ?>
          $wert
          ===== Beispiel passwd_enhanced.php ==== Das ganze kann man auch etwas aufwendiger mit sortierbaren Überschriften gestalten. = 0 && $_GET['col'] < 6) { //Validitätsprüfung, nur Spalten 0..5 erlaubt $sort_column = $_GET['col']; } else { echo "

          Finger weg von der URL!!!

          "; $sort_column = 0; } } else { $sort_column = 0; } ?> Userliste , ) 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; ?> "; foreach ($userarray as $wert) { $row .= ""; } $row .= ""; echo $row; } ?>
          Login UID GID Name Home Shell $wert
          ====== function / include ====== Eigene Funktion: //... \n"; print_r($daten); echo "\n\n"; } //... Funktionen können auch in eigene Dateien ausgelagert und mittels "include()" bzw. "include_once()" eingebunden werden. ===== Parameter-Übergabe ===== ===== Globale Variablen ===== ===== array_map() ===== Wendet eine Funktion auf alle Elemente eines Arrays an. ====== 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. ... 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 Dump

          Session Dumper

          ====== Formulare ====== ===== type="text" =====

          ===== type="select" =====

          Zahlen addieren

          ===== type=radio ===== //...
          Montag Dienstag Mittwoch Donnerstag Freitag Samstag Sonntag
          //...
          ===== type=checkbox ====== per cron ausführen
          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. ===== 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)

          ====== 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 '&'. '"' (doppeltes Anführungszeichen) wird zu '"', wenn ENT_NOQUOTES nicht gesetzt ist. "'" (einfaches Anführungszeichen) wird nur zu ''', wenn ENT_QUOTES gesetzt ist. '<' (kleiner als) wird zu '<' '>' (größer als) wird zu '>' Bei Funktionen wie "print_r" muss man etwas aufwendiger durch eine Zusatzfunktion erst die Zeichenkette (return true) zurückgeben, um diese z.B. durch htmlspecialchars umwandeln zu lassen. \n"; //print_r($daten); echo htmlspecialchars(print_r($daten, true)); echo "\n\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. = 0 && $_GET['col'] < 6) { //Validitätsprüfung, nur Spalten 0..5 erlaubt $sort_column = $_GET['col']; } else { echo "

          Finger weg von der URL!!!

          "; $sort_column = 0; } } else { $sort_column = 0; } $path = "/etc/passwd"; $userlist = read_passwd($path); ?> Userliste

          Sortierung nach Spalte

          "; foreach ($userarray as $wert) { $row .= ""; } $row .= ""; echo $row; } ?>
          Login UID GID Name Home Shell $wert
          , ) while (($line = fgets($fh, 2048)) !== false) { // fgets liefert die nächste Zeile und "false", wenn es keine nächste Zeile mehr gibt. // 2048 ist dabei die Zeilenlänge (Anzahl der Zeichen) $userarray = explode(":", $line); array_splice($userarray, 1, 1, array()); //Passwort-"Spalte" löschen // Ans Ende des Arrays anhängen $userlist[] = $userarray; } fclose($fh); //filehandle schließen return $userlist; //neues Array mit allen Daten zurückliefern } function cmp_by_col($a, $b) { global $sort_column; //Global, wird oben gesetzt if ($sort_column == 1 || $sort_column == 2) { // UID || GID return $a[$sort_column] - $b[$sort_column]; } $a[$sort_column] = strtolower($a[$sort_column]); $b[$sort_column] = strtolower($b[$sort_column]); return strcmp($a[$sort_column],$b[$sort_column]); // return strcasecmp($a[$sort_column],$b[$sort_column]) } table.colored_table th { background: lightblue; } table.colored_table tr:nth-child(even) { background: lightgray; } /* das ist im CSS die einzig erlaubte Art, Kommentare zu schreibe */ table.colored_table tr:nth-child(odd) { background: white; } ===== 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

          Urlaubsfotos

          ".$_SESSION['upload_msg']."

          "; $_SESSION['upload_msg'] = false; ?>
          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

          Zahlen addieren

          Ergebnis der Berechung: $ergebnis

          "; else echo "

          Formular nicht korrekt ausgefüllt

          "; ?>
          '+', 'sub' => '-', 'mul' => '*', 'div' => '/'); /* // verschachteltes Array $calc_opterator = array(['add', '+'], ['sub', '-'], ['mul', '*'], ['div', '/'] ); */ s für Formular Name:
          Strasse:
          PLZ:
          Ort:
          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(); }); 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'; } 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; }