Webtechnologien Wintersemester 2024

PHP

Datenbankzugriff

Möglichkeiten

  • PHP bietet von Hause aus verschiedene Wege, um mit Datenbanken zu kommunizieren
  • Jeweils eigene Treiber für verschiedene DBS

Schaubild

  • MySQL, PostgreSQL oder SQLite.

Verbindung mit MySQL-Datenbanken

  • 3 mögliche APIs:
    • mysql – alte Variante
    • mysqli – verbesserte Version der alten Variante
    • PDO – neue Variante
  • wichtige Funktionen: query, prepare, bindParam, execute und fetch
  • Probleme
    • Zu leicht, unsicheren Code zu schreiben
    • Kompliziert, Datenbank zu wechseln

PDO – PHP Database Object

  • Abstraktionsschicht für den Datenzugriff
  • Objektorientiert (kann nicht prozedural benutzt werden)
<?php
   $connection = new PDO('sqlite:users.db');
   $statement = $connection->query('SELECT * FROM users');
   $result = $statement->fetchAll();
   var_dump($result);
?>
  • Aufbau der Verbindung → Zugriff auf die Datenbank → Abbau der Verbindung
  • Gleiche Befehle, egal welche Datenbank gerade benutzt wird
  • Keine Datenbank-Abstraktion oder ORM, SQL immer noch Handarbeit
  • prüfen per php -i | grep PDO oder <?php phpinfo() ?>

PDO – Init

<?php class Storage {
private $connection;
public function __construct() {
   try {
      $this->connection = new PDO(
         "mysql:host=$host;dbname=$name;charset=utf8", $user, $pass);
      // $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
      $this->connection->setAttribute(
         PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
   } catch (PDOException $e) { die($e->getMessage()); }
}
public function __destruct() { $this->connection = null; }
?>
  • Gleiche Befehle, egal welche Datenbank gerade benutzt wird
  • Keine Datenbank-Abstraktion oder ORM, SQL immer noch Handarbeit
  • Standard-Error-Mode ist silent, kann aber geändert werden (warning, exception)
  • $db->getAvailableDrivers() um verfügbare Treiber aufzulisten

PDO – Query

<?php
   $users = $this->connection->query('SELECT * FROM users');
   
   foreach ($users as $user) {
      var_dump($user);
   }
?>

PDO – Prepared Statements

<?php
   $id = $_GET['id'];
   $result = $this->connection->query(
      "SELECT * FROM users WHERE id = $id"); // BÖSE!!!

   $statement = $this->connection->prepare(
      'UPDATE answers SET votes = votes + 1 WHERE id = :id');
   $statement->bindParam(':id', $id, PDO::PARAM_INT);
   $result = $statement->execute();
?>
  • gibt auch PDO::quote, aber Prepared Statements der Erfahrung nach besser
  • Enthalten entgegen üblicher SQL-Statements keine Parameter, sondern nur Platzhalter.
  • Datenbank bekommt Parameter separat und prüft diese
  • Platzhalter können auch ? sein, aber benannte besser lesbar
  • bindParam: Platzhalter, Variable, Datentyp, Länge, Optionen
  • execute: Kann Array als Parameter erhalten und iteriert dann über Platzhalter (werden alle als String behandelt)

PDO – Fetch

<?php
   while($row = $statement->fetch()) {
       print_r($row);
   }
   $result = $statement->fetch(PDO::FETCH_CLASS, 'User');
   $result = $statement->fetchObject('User');
   $result = $statement->fetchAll();
?>
  • Modes
    • PDO::FETCH_ASSOC: Assoziatives Array
    • PDO::FETCH_BOTH: Mischung aus numerisch indexiertem und assoziativem Array
    • PDO::FETCH_CLASS: Erzeugt Objekt zur entsprechenden Klasse
    • PDO::FETCH_OBJ: Erzeugt ein anonymes Objekt
    • und mehr