Tag Archives: PDO

webmastering

A Ty w jaki sposób łączysz się z bazą danych?

Tytuł zabrzmiał jak w Matrik­sie. Chodzi oczy­wi­ście o łącze­nie apli­ka­cji PHP z bazą danych. Dzisiaj pokażę w jaki sposób w niewiel­kich projek­tach radzę sobie z przy­go­to­wa­niem obiektu PDO do pracy z bazą danych. Trudno żebym w niewiel­kiej „stronce” zaprzę­gał jakiś Zend Framework.

Napi­sa­łem sobie dawno temu klasę narzę­dziową do tworze­nia obiektu PDO. Imple­men­tuję w niej wzorzec projek­towy single­ton, a więc mam pewność, że gdzie­kol­wiek w kodzie żądam PDO, zawsze dostaję ten sam obiekt. Jeżeli chodzi o sam single­ton, to na jego temat można prze­czy­tać zarówno we Wzor­cach Projek­to­wych1 jak i w Design Patterns.2 Zresztą to w Googlu wysko­czy pier­dy­lion wyników ;-)

Używa­nie klasy jest dzie­cin­nie proste. Należy sobie jedno­ra­zowo prze­edy­to­wać stałe klasy doty­czące połą­cze­nia z bazą, a następ­nie w kodzie wywo­ły­wać metodę DBHandler::getPDO()

Poni­żej podaję kod klasy. Bierz­cie i jedzcie ;-)

<?php
class DBHandlerException extends PDOException {
}
 
/**
 * @author Dawid 'Spiechu' Spiechowicz
 * @license see http://spiechu.pl/o-publikowanym-kodzie/
 */
class DBHandler {
 
  /**
   * Dane bazy danych
   */
  const DB_HOST = 'localhost';
  const DB_NAME = 'nazwa bazy';
  const DB_USER = 'nazwa usera';
  const DB_PASS = 'haslo';
 
  /**
   * Sterownik bazy danych
   */
  const DB_DRIVER = 'mysql';
 
  /**
   * Czy wyswietlac dokladne komunikaty bledow
   */
  const DEBUG_MODE = true;
 
  /**
   * @var PDO singleton PDO
   */
  private static $pdo = null;
 
  /**
   * Zwraca singleton PDO lub wyswietla komunikat bledu i zwraca null.
   * @return PDO|null
   */
  public static function getPDO() {
    try {
      if (self::$pdo === null) {
        self::$pdo = self::createPDO();
      }
      return self::$pdo;
    }
    catch (DBHandlerException $e) {
      echo $e->getMessage();
      return null;
    }
  }
 
  /**
   * @return PDO zwraca nowa instancje PDO
   * @throws DBHandlerException
   */
  private static function createPDO() {
    if (!extension_loaded('PDO')) throw new DBHandlerException('Brak modulu PDO');
    try {
      $pdo = new PDO(
         self::DB_DRIVER . ':host=' . self::DB_HOST . ';dbname=' . self::DB_NAME, 
         self::DB_USER, 
         self::DB_PASS,
         array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
      $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
      $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
      return $pdo;
    }
    catch(PDOException $e) {
      if (self::DEBUG_MODE == true) {
        throw new DBHandlerException("Blad bazy danych : {$e->getMessage()}");
      }
      else {
        throw new DBHandlerException('Blad bazy danych');
      }
    }
  }
 
  /**
   * Zapobiega tworzeniu obiektu.
   */
  private function __construct() {
    throw new Exception('Nie mozna stworzyc tego obiektu!');
  }
 
  /**
   * Zapobiega klonowaniu obiektu.
   */
  private function __clone() {
    throw new Exception('Nie mozna klonowac tego obiektu!');
  }
}

Powy­żej widać kilka sztu­czek. Przede wszyst­kim konstruk­tor ma zasięg prywatny, co zapo­biega stwo­rze­niu instan­cji klasy z zewnątrz. Mało tego, próba wywo­ła­nia go z wnętrza klasy spowo­duje wyrzu­ce­nie wyjątku. To samo z metodą __clone().

Przy konfi­gu­ra­cji obiektu PDO usta­wiam tryb błędów na wyjątki, które wyła­puję i w zależ­no­ści od usta­wio­nej stałej DEBUG_MODE wyświe­tlam komu­ni­katy błędów PDO lub nie. Frag­ment $pdo->query('SET NAMES utf8') usta­wia kodo­wa­nie znaków na Unicode. Niestety nie znala­złem lepszej metody. Rezul­taty zapy­tań domyśl­nie będą dostępne w postaci tablicy asocjacyjnej.

  1. E. Gamma (i in.) : Wzorce projek­towe. Elementy opro­gra­mo­wa­nia obiek­to­wego wielo­krot­nego użytku. Gliwice : Helion, 2010, s. 130–136.
  2. E. Freeman (i in.) : Head First Design Patterns. Gliwice : Helion, 2005, s. 197–216.