Einführung

Diese kleine Programmierübung soll die generellen Zugriffe per PHP / MySQLi Technik darstellen. Hierzu sollen die Befehlsstrukturen mit OOP / MySQLi / Prepared Statements umgesetzt werden. Die hier dargestellten Beispielskripte sind eine Zusammenfassung von PHP-Datenbank-Übungen, wie wir sie im Rahmen unserer "PHP & MySQL"-Seminare für das Zertifikat "CMS Online Designer (VHS)" schulen.

Schwerpunkt liegt auf der Umsetzung mit OOP (Prepared Statments) - daher hier eine kurze Darstellung / Erinnerung

Prozedural es werden die eingebauten (mysqli_connect, mysqli_query) oder benutzerdefinierten Funktionen (s.o. arrayAusgabe) einzeln programmiert und aufgerufen
OOP wir nutzen bestehende oder selbst definierte Klassen und Objekte
modern, effizient - erspart Zeit

Sehen Sie hierzu auch meine ausführlicheren Darstellungen zu unseren "PHP & MySQL"-Seminaren.

 

Meinen Teilnehmern wurden die folgenden Übungsdatenbanken dargestellt.

Datenbank - TechnikAutor - Beschreibung
news Dr. Florence Maurice - PHP 5.5 und MySQL 5.6 - dpunkt Verlag 2014
Kapitel 11 PHP & MySQL - Kap. 11.6 Prepared Statements - auf alles bestens vorbereitet
siehe hierzu auch meine PHP & MySQL Bibliothek
kontakte Christian Wenz; Internet magazin 02/2008 - MySQL mit PHP "Der Datenturbo"
Einführung in die Techniken OOP, mysqli, Prepared Statements
mysqli_prepare Konnektion mit Datenbank und Darstellung der OOP-Vorgehensweise
gemäß PHP-Online-Tutorial

Aus den Skriptbeispielen ergibt sich die vorliegende Kontakteverwaltung mit den folgenden Techniken:

  • PHP mysqli mit OOP und Prepared Statement
  • Fehler- und Ausnahmenbehandlungen mit try / catch Blöcken
    Anm.: für die Funktionalität nicht wichtig - Link zu php.net Website 
  • Einfachste Formularbehandlung
  • Konzentration auf Darstellung Grundoperationen CRUD (Create, Read, Update, Delete)

Datenbank

Wir stellen uns die nötige Datenbank bereit. Für die vorliegende Kontaktverwaltung benötigen Sie einen XAMPP und die Datenbank phpmysql_kontakte.
Sie können sich natürlich eine eigene DB erstellen und müssen dann im DB-Include-Skript die Infos anpassen.

  • Vorgehen: mit phpMyAdmin eine Datenbank phpmysql_kontakte erstellen;
    danach Tabelle importieren mittels tabelle-kontakt-erstellen.sql  .
  • Alternative: gesamte Datenbank phpmysql_kontakte inklusive Tabelle kontakt mit beiliegenden SQL-Dump db-phpmysql_kontakte-tabelle-kontakt-erstellen.sql in DB-Server importieren.

PHP-Skripte

Die beteiligten PHP-Skripte wurden ausgiebig kommentiert und werden hier als Code (bzw. Download) dargestellt.

 

db.inc.php

Datenbank konnektieren und mysqli-Objekt bereitstellen.

View source
  1. <?php
  2. // DB-Konnection und Fehlerbehandlung für Datenbankserver / Datenbank
  3. $mysqli = new mysqli("localhost", "root", "", "phpmysql_kontakte");
  4. if ($mysqli->connect_error) {
  5. echo "Fehler bei der Verbindung: " . mysqli_connect_error();
  6. exit();
  7. }
  8. if (!$mysqli->set_charset("utf8")) {
  9. echo "Fehler beim Laden von UTF8 ". $mysqli->error;
  10. }
  11. ?>

 

index.php

Aktuelle Kontaktverwaltung auslesen und anzeigen.

View source
  1. <?php
  2.     // Einfügen der Datenbank-Konnektion (und ggf. Helfer-Klassen)
  3.     // Objekt für DB: mysqli (benannt wie die PHP-MySQLi-Klasse mysqli
  4.     require_once 'db.inc.php';
  5. ?>
  6. <!DOCTYPE HTML>
  7. <html lang="de-DE">
  8. <head>
  9.     <meta charset="UTF-8">
  10.     <title>Kontakteverwaltung mit OOP (Prepared Statements)</title>
  11. </head>
  12.  
  13. <body>
  14. <table style="width: 500px;">
  15.     <thead> <!-- Tabellenkopf für Ausgabe Kontakte -->
  16.         <tr>
  17.             <th>Nr.</th> <th>Vorname</th> <th>Nachname</th> <th>E-Mail</th> <th>Aktionen</th>
  18.         </tr>
  19.     </thead>
  20. <tbody>
  21. <?php
  22. try {    // Kapselungen in try/catch-Blöcke zur erweiterten Fehlerbehandlung
  23. // Nutzen von MySQLi-Prepared-Statements Technik (Klasse: mysqli_stmt)
  24. // SQL-SELECT vorbereiten - sortieren nach id - aufsteigend
  25. if ($stmt = $mysqli->prepare("SELECT id, vorname, nachname, email FROM kontakt ORDER BY id ASC")) {
  26.     // Abfrage (Query) durchführen
  27.     $stmt->execute();
  28.     // Ergebnisse (Spalten) an eigene / definierte Variablen binden
  29.     $stmt->bind_result($id, $vorname, $nachname, $email);
  30.  
  31.     // Mit Methode fetch() die Ergebnisse in Schleife durchlaufen / ausgeben
  32.     while($stmt->fetch()) {
  33.         echo "<tr>\n";
  34.         echo "<td><strong>" . $id . "</strong></td>"
  35. . "<td>" . htmlspecialchars($vorname) . "</td>"
  36.          . "<td>" . htmlspecialchars($nachname) . "</td>"
  37.          . "<td>" . htmlspecialchars($email) . "</td>"
  38.          . "<td> <a href=\"bearbeiten.php?id=" . (int)$id . "\">bearbeiten</a>"
  39.          . "| <a href=\"loeschen.php?id=" . (int)$id . "\">löschen</a> </td>\n";
  40.         echo "</tr>\n";
  41.     }    // end while
  42.     // Prepared Statement Objekt wieder freigeben
  43.     $stmt->close();
  44. }    // Ende der IF-Then-Anweisungen
  45.  
  46.     // Datenbankverbindungsobjekt freigeben
  47.     $mysqli->close();
  48.  
  49.     // Fehler mit try/catch abfangen/ausgeben
  50.     } catch (Exception $ex) {
  51.         echo '<tr><td colspan="5">Fehler!</td></tr>';
  52.     }
  53. ?>
  54.     </tbody>
  55. </table>
  56.  
  57. <p>
  58.     <a href="neu.php">Neuen Kontakt anlegen</a>
  59. </p>
  60. </body>
  61. </html>

 

neu.php

Einen neuen Datensatz aufnehmen in Tabelle kontakt.

View source
  1. <?php
  2.     require_once 'db.inc.php';
  3. ?>
  4. <!DOCTYPE HTML>
  5. <html>
  6. <head>
  7.     <meta charset="UTF-8">
  8.     <title>Neu - Kontaktverwaltung</title>
  9. </head>
  10.  
  11. <body>
  12. <?php
  13. // Formular validieren: (hier sehr einfach / grob)
  14. // die Variablen vorname, nachname, email müssen
  15. // alle per Methode Post übergeben worden sein und
  16. // alle den Datentyp String besitzen und die email darf nicht leer sein!
  17. if (isset($_POST['vorname']) && is_string($_POST['vorname']) &&
  18. isset($_POST['nachname']) && is_string($_POST['nachname']) &&
  19. isset($_POST['email']) && is_string($_POST['email']) && !empty($_POST['email'])) {
  20.  
  21.     // wieder so eine try/catch Konstruktion zur Fehler-/Ausnahmebehandlung
  22.     try {
  23.         // Prepared Statement: Einfügen-SQL-String mit Platzhaltern (?)
  24.         $stmt = $mysqli->prepare('INSERT INTO kontakt (vorname, nachname, email) VALUES (?, ?, ?)');
  25.         // im Prepared Statement Objekt die übergebenen POST-Inhalte binden
  26.         $stmt->bind_param('sss', $_POST['vorname'], $_POST['nachname'], $_POST['email']);
  27.         // SQL Einfügen ausführen in IF-Bedingung, also: bei Erfolg
  28.         if ($stmt->execute()) {
  29.             // spezielle Methode des DB-Konnektions-Objekts nutzen
  30.             // Methode insert_id() ermittelt uns die neu erzeugte id des Datensatz
  31.             $id = $mysqli->insert_id;
  32.             // Infos zu neuem Datensatz (id) ausgeben, falls alles funktioniert hat
  33.             echo 'Kontakt eingetragen (ID: ' . $id . ')!';
  34.             } else {
  35.                 echo 'Fehler: ' . htmlspecialchars($db->error) . '!</td></tr>';
  36.             }
  37.             
  38.         // alle Objekte wieder freigeben    
  39.         $stmt->close();
  40.         $mysqli->close();
  41.         
  42.         // hier wieder der catch-Teil zur try/catch Technik
  43.         } catch (Exception $ex) {
  44.             echo 'Fehler!';
  45.         }
  46.     }    // es folgt ein leeres HTML-Formular für neue Datensätze / Kontakte
  47. ?>
  48. <form method="post" action="">
  49. <table>
  50. <thead>
  51.     <tr> <th>Information</th> <th>Wert</th> </tr>
  52. </thead>
  53. <tbody>
  54.     <tr>
  55.         <td>Vorname</td> <td><input type="text" name="vorname" /></td>
  56.     </tr>
  57.     <tr>
  58.         <td>Nachname</td> <td><input type="text" name="nachname" /></td>
  59.     </tr>
  60.     <tr>
  61.         <td>E-Mail</td> <td><input type="text" name="email" /></td>
  62.     </tr>
  63. </tbody>
  64. </table>
  65.     <input type="submit" value="Kontakt anlegen" />
  66. </form>
  67. <p> <a href="index.php">Zur Startseite</a> </p>
  68. </body>
  69. </html>

 

loeschen.php

Einen Datensatz nach Rückfrage aus Tabelle kontakt löschen.

View source
  1. <?php
  2.     require_once 'db.inc.php';
  3. ?>
  4. <html>
  5. <head>
  6.     <meta charset="UTF-8">
  7.     <title>Löschen - Kontaktverwaltung</title>
  8. </head>
  9.  
  10. <body>
  11. <?php
  12. // Falls keine id per GET übergeben worden ist,
  13. if (!isset($_GET['id'])) {
  14.     // dann bitte einfach direkt wieder auf index.php
  15. header('Location: index.php');
  16.  
  17. // ansonsten, falls das POST-Feld ok nicht übergeben wurde
  18. } elseif (!isset($_POST['ok'])) {
  19.     // setze Variable id auf Ganzzahl von per GET übergebene Variable id
  20. $id = (int)$_GET['id'];
  21.     // Und wieder: try/catch Blöcke zur Fehler-/Ausnahmebehandlung
  22. try {
  23.         // Prepared Statement: SQL-Select String für Datensatz mit GET-id
  24.         if ($stmt = $mysqli->prepare('SELECT id, vorname, nachname, email FROM kontakt WHERE id=?')) {
  25.             // Binde GET-id (als integer) an Prepared Statement
  26.             $stmt->bind_param("i", $id);
  27.             // Führe SQL-Select aus - Ergebnis für Datensatz liegt dann vor
  28.             $stmt->execute();
  29.             // Binde die folgenden Variablen an die Ergebnisse
  30.             $stmt->bind_result($id, $vorname, $nachname, $email);
  31.             // Hole uns die Ergebnisse
  32.             $stmt->fetch();
  33.         // Meldung / Feedback zum Löschdatensatz ausgeben
  34.         // hier wird jetzt verstecktes Form-Feld ok genutzt (type hidden)!
  35.         printf('Wollen Sie wirklich den Datensatz Nr. %s (%s %s, %s) löschen?<br />' .
  36. '<form method="post" action=""><input type="hidden" name="ok" value="true" /><input type="submit" value="L&ouml;schen" /></form>',
  37. (int) $id,
  38. htmlspecialchars($vorname),
  39. htmlspecialchars($nachname),
  40. htmlspecialchars($email));
  41.  
  42.         } else { // Falls es Fehler bei Prep-Stmt im ersten if gab:
  43.             echo 'Fehler: ' . htmlspecialchars($mysqli->error) . '!</td></tr>';
  44.         }
  45.  
  46. } catch (Exception $ex) { // catch zum try/catch-Block
  47.         echo 'Fehler!';
  48.     } // Ende catch-Teil
  49.     
  50.     } else {
  51.         // Variable id aus Ganzzahl der per GET übergebenen Variable id
  52.         $id = (int)$_GET['id'];
  53.         // try/catch again
  54.         try {
  55.             // Prepared Statemen SQL-String Delete mit Platzhalter (?) bei where id
  56.             if ($stmt = $mysqli->prepare("DELETE FROM kontakt WHERE id=?")) {
  57.             // Platzhalter muss gebunden werden
  58.             $stmt->bind_param("i", $id);
  59.             // SQL ausführen
  60.             $stmt->execute();
  61.             // Objekte zurückgeben
  62.             $stmt->close();
  63.             $mysqli->close();
  64.             // Ausgabe / Quittung
  65.             echo 'Datensatz gelöscht!';
  66.             } else {
  67.                 echo 'Fehler: ' . htmlspecialchars($mysqli->error) . '!</td></tr>';
  68.             }
  69.         } catch (Exception $ex) {
  70.             echo 'Fehler!';
  71.         }
  72.     }
  73. ?>
  74. <p><a href="index.php">Zur Startseite</a></p>
  75. </body>
  76. </html>

 

bearbeiten.php

Einen Datensatz zum Ändern / Aktualisieren bereitstellen und in Tabelle kontakt aktualisieren.

View source
  1. <?php
  2.     require_once 'db.inc.php';
  3. ?>
  4. <html>
  5. <head>
  6.     <meta charset="UTF-8">
  7.     <title>Bearbeiten - Kontaktverwaltung</title>
  8. </head>
  9.  
  10. <body>
  11. <?php
  12. // Falls keine id per GET übergeben worden ist,
  13. if (!isset($_GET['id'])) {
  14.     // dann bitte einfach direkt wieder auf index.php
  15. header('Location: index.php');
  16.  
  17. // ansonsten, "kleine" Validierung Formular:
  18. // vorname, nachname, email müssen alle per POST übergeben sein!    
  19. } elseif (isset($_POST['vorname']) && isset($_POST['nachname']) && isset($_POST['email'])) {
  20. try {
  21.         // Prepared Statement SQL-Befehl Update mit Platzhaltern
  22.         $stmt = $mysqli->prepare('UPDATE kontakt SET vorname=?, nachname=?, email=? WHERE id=?');
  23.         // Platzhalter binden mit 3 Strings und 1 integer Wert
  24.         $stmt->bind_param('sssi', $_POST['vorname'], $_POST['nachname'], $_POST['email'], $id);
  25.         // per GET übergebene hier wieder (siehe auch unten auf Variable id
  26.         $id = (int)$_GET['id'];    
  27.         // SQL-Update ausführen und Meldung(en) erzeugen
  28.         if ($stmt->execute()) {
  29.             echo 'Kontakt aktualisiert!';
  30.          } else {
  31.             echo 'Fehler: ' . htmlspecialchars($mysqli->error) . '!</td></tr>';
  32.          }
  33.         // Statement Objekt zurückgeben
  34.         $stmt->close();
  35.         } catch (Exception $ex) {
  36.             echo 'Fehler!';
  37.         }
  38.             // ende von elseif
  39. } else {     // Falls keine POST-Variablen
  40.     // Variable id auf per GET übergebene Variable id setzen
  41. $id = (int)$_GET['id'];
  42. try {    // und wieder try/catch Block - Beachten Bracket endet nicht vor HTML-Code!
  43.         // Prepared Statement: mit Select die Daten für den gewünschten Datensatz auslesen
  44.         // auch hier wird die geschweifte Klammer (Bracket) erst nach dem HTML-Code geschlossen!
  45.         if ($stmt = $mysqli->prepare("SELECT id, vorname, nachname, email FROM kontakt where id=?")) {
  46.             // Variable id an Prep Stmt Select binden
  47.             $stmt->bind_param("i", $id);
  48.             // SQL ausführen
  49.             $stmt->execute();
  50.             // Ergebnisse an gewünschte Variablen binden
  51.             $stmt->bind_result($id, $vorname, $nachname, $email);
  52.             // die Variablen holen
  53.             $stmt->fetch();
  54.             // es folgt das HTML-Formular... hier mit eingefügten Werten aus Select...
  55. ?>
  56. <form method="post" action="">
  57. <table>
  58. <thead>
  59.     <tr>
  60.         <th>Information</th> <th>Wert</th>
  61.     </tr>
  62. </thead>
  63. <tbody>
  64.     <tr>
  65.         <td>Vorname</td>
  66.         <td><input type="text" name="vorname" value="<?php echo htmlspecialchars($vorname); ?>" /></td>
  67.     </tr>
  68.     <tr>
  69.         <td>Nachname</td>
  70.         <td><input type="text" name="nachname" value="<?php echo htmlspecialchars($nachname); ?>" /></td>
  71.     </tr>
  72.     <tr>
  73.         <td>E-Mail</td>
  74.         <td><input type="text" name="email" value="<?php echo htmlspecialchars($email); ?>" /></td>
  75.     </tr>
  76. </tbody>
  77. </table>
  78. <input type="submit" value="Kontakt aktualisieren" />
  79. </form>
  80.  
  81. <?php
  82.         } else {
  83.             echo 'Fehler: ' . htmlspecialchars($mysqli->error) . '!</td></tr>';
  84.         }
  85.         $mysqli->close();
  86.         } catch (Exception $ex) {
  87.             echo 'Fehler!';
  88.         }
  89.     }
  90. ?>
  91. <p><a href="index.php">Zur Startseite</a></p>
  92. </body>
  93. </html>

 

Wichtig: die hier dargestellten Codes sollen nur Technikprinzipien darstellen und ich gebe keinerlei Gewähr auf Funktion ode gar Sicherheit der Codezeilen.

Ihr Trainer Joe Brandes
Braunschweig, Mai 2017