IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

4. diel - Práca s MySQL v PHP - Použitie ovládača PDO

V predchádzajúcom dieli seriálu http://www.itnetwork.cz/...adace-mysqli sme si ukázali, že objektové riešenie prístupu k databáze je možno o niečo dlhšia, než procedurálne, ale zato je o niečo prehľadnejšie a robustnejšie.

Databázový svet sa neobmedzuje len na databázu MySQL, ale použiteľných databáz je v ňom niekoľko desiatok. Každá sa ovláda trochu inak a pre každú vznikol nový ovládač. Preto vývojári prišli s myšlienkou vytvorenia jednotného ovládača, ktorý sa z pohľadu programátora bude správať zakaždým rovnako, bez ohľadu na typ pripojenej databázy.

Prvé pokusy dopadli fiaskom, pretože vytvoriť kompletné rozhranie pre všetky typy databáz sa ukázalo ako nemožné. Buď bolo primitívne a nedokázalo využiť všetkých vlastností použitej databázy, alebo bola jeho vnútorná štruktúra značne komplikovaná, aby emuloval nedostatky iných databáz.

Bol teda vytvorený kompromis. Vcelku jednoduchá trieda, ktorá pre každú spoločnú vlastnosť všetkých databáz ponúka rovnakú metódu ovládania. Niektoré metódy sú funkčné len pre niektoré databázy. Ukázalo sa to ako veľmi výhodné riešenie nazvané

PHP Data Objects

známejší pod skratkou PDO. Ako názov napovedá, je to objektové rozhranie databáz pre PHP. Procedurálne rozhranie budeme hľadať márne.

Ako obvykle tu ako prvý predvediem trochu nešikovný kód odvodený z predchádzajúcich príkladov.

<?php
class Adresar{

  private $spojeni;
  private $navrat;
  private $seznam;

  function __construct($host,$user,$pass,$name){
    $this->spojeni= @new PDO("mysql:host=$host;dbname=$name",$user,$pass);
    if ($this->spojeni->errorCode()) {
      throw new Exception($this->spojeni->errorCode());
    }
    $this->spojeni->query("SET NAMES utf8");
  }

  function query($query) {
    $this->navrat=$this->spojeni->query($query);
    if(!$this->navrat) {
      throw new Exception($this->navrat->errorCode());
    }
    $this->seznam=$this->navrat->fetchAll(PDO::FETCH_ASSOC);
    if(!sizeof($this->seznam)) {
      throw new Exception("Tabulka je prázdná");
    }
  }

  function getHeaders(){
    return array_keys($this->seznam[0]);
  }

  function getRows(){
    return $this->seznam;
  }
}

try{
  $adresar=new Adresar("localhost","kit","","test");
  $adresar->query("SELECT * FROM adresar");
  $row=$adresar->getHeaders();
  echo("<table border=\"1\">\n");
  echo("<tr>\n");
  foreach($row as $value) {
    echo("<th>".$value."</th>\n");
  }
  echo("</tr>\n");
  foreach($adresar->getRows() as $row){
    echo("<tr>");
    foreach($row as $value) {
      echo("<td>".htmlspecialchars($value)."</td>");
    }
    echo("</tr>\n");
  }
  echo("</table>\n");
} catch(Exception $e) {
  echo "Tabulku nelze vypsat<br />\n";
  echo $e->getMessage(),"\n";
}

Je vidieť, že jednoduchou výmenou ovládače som prakticky nič nezískal. Je teda potrebné sa pozrieť do manuálu a vyžmýkať z PDO čo vie. Na prvom mieste by som uviedol výnimky. Len je potreba ovládačmi oznámiť, že ich chceme využívať. Tým sa program výrazne skráti, ale hlavne sa mi už nestane, že by som zabudol otestovať výsledok niektorého dotazu.

<?php
class Adresar{

  private $spojeni;
  private $navrat;
  private $seznam;

  function __construct($host,$user,$pass,$name){
    $options=array(
      PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
      PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"
      );
    $this->spojeni= @new PDO("mysql:host=$host;dbname=$name",$user,$pass,$options);
  }

  function query($query) {
    $this->navrat=$this->spojeni->query($query);
    $this->seznam=$this->navrat->fetchAll(PDO::FETCH_ASSOC);
    if(!sizeof($this->seznam)) {
      throw new Exception("Tabulka je prázdná");
    }
  }

  function getHeaders(){
    return array_keys($this->seznam[0]);
  }

  function getRows(){
    return $this->seznam;
  }
}

// pokračování viz předchozí příklad

V uvedenom príklade som zmenil iba triedu Adresar, zvyšok skriptu som ponechal bez zmeny. Je vidieť, že ku sprehľadnenie naozaj došlo, pritom chyby sú stále ošetrené. Navyše sa mi podarilo pri otváraní databázy vpašovat prvý SQL dotaz "SET NAMES utf8". Tento príkaz (namiesto "utf8" môže byť "cp1250" či "LATIN2" podľa preferencií) je nutný, inak si databázy bude myslieť, že ukladaná dáta budú vo švédskom kódovania.

A ako vždy sa mi to nepáči, pretože je toho písanie stále príliš veľa. Pustím sa teda do optimalizácie. Tu je kompletné riešenie v mojom štýle:

<?php
class Adresar{

  private $spojeni;
  private $navrat;
  private $seznam;

  function __construct($host,$user,$pass,$name){
    $options=array(
      PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
      PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"
      );
    $this->spojeni= @new PDO("mysql:host=$host;dbname=$name",$user,$pass,$options);
    $this->navrat=$this->spojeni->query("SELECT * FROM adresar");
    $this->seznam=$this->navrat->fetchAll(PDO::FETCH_ASSOC);
    if(!sizeof($this->seznam)) {
      throw new Exception("Tabulka je prázdná");
    }
  }

  function __toString() {
    $headers='<tr><th>'.implode('</th><th>',array_keys($this->seznam[0])).'</th></tr>';
    $rows=array();
    foreach($this->seznam as $row){
      $rows[]='<tr><td>'.implode('</td><td>',array_map('htmlspecialchars',$row)).'</td></tr>';
    }
    $table=implode("\n",$rows);
    return <<<EOT
<table border="1">
$headers
$table
</table>

EOT;
  }
}

try{
  $adresar=new Adresar("localhost","kit","","test");
  echo $adresar;
} catch(Exception $e) {
  echo "Tabulku nelze vypsat<br />\n";
  echo $e->getMessage(),"\n";
}

Tentokrát som sa s tým toľko nepáral a napchal SQL dotaz priamo do konstruktoru triedy Adresar. Nie je to práve ideálne, pretože málokedy potrebujeme databáze položiť jediný dotaz a opakované otváranie databázy je drahé (časovo náročné). Ponúka sa teda otvárať databázu mimo triedu Adresar, trochu si ju vylepšiť a odovzdať ju konstruktoru triedy Adresar ako objekt. Bude to síce o trochu dlhšie, ale pri viacnásobnom použití sa mi to bohato vráti. O tom však až nabudúce.


 

Predchádzajúci článok
Práca s MySQL v PHP - Použitie ovládača MySQLi
Všetky články v sekcii
Ostatné tutoriály v PHP
Preskočiť článok
(neodporúčame)
Práca s MySQL v PHP - PDO objektovo a modulárne
Článok pre vás napísal Kit
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Jsem spokojeným uživatelem operačních systémů založených na linuxovém jádře. Zejména openSUSE a Ubuntu. Pro psaní veškerých textů a programů používám vynikající textový editor Vim. Aplikace se snažím psát vždy v tom nejvhodnějším programovacím jazyk...
Aktivity