IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 5 - Práca s MySQL v PHP - PDO objektovo a modulárne

V predchádzajúcom článku http://www.itnetwork.cz/...ovladace-pdo som napísal, že by bolo vhodné oddeliť prácu s databázou do samostatnej triedy, aby sme s ňou mohli pracovať na viacerých miestach - nielen v triede Adresar a nemuseli ju zakaždým znova otvárať. Otváranie databázy je totiž časovo náročná operácia. Preto ju v aplikácii otvoríme len raz a použijeme všade, kde sa nám bude hodiť.

Tentokrát už bude meno triedy mydb na mieste. Vytvoril som vlastné jednoduchú nadstavbu databázy.

<?php
// soubor MyDB.class.php

class MyDB{
  private $spojeni;

  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,$param=Array()){
      $navrat=$this->spojeni->prepare($query);
      $navrat->execute($param);
      return $navrat->rowCount();
  }

  function queryOne($query,$param=Array()){
      $navrat=$this->spojeni->prepare($query);
      $navrat->execute($param);
      return $navrat->fetch(PDO::FETCH_ASSOC);
  }

  function queryAll($query,$param=Array()){
      $navrat=$this->spojeni->prepare($query);
      $navrat->execute($param);
      return $navrat->fetchAll(PDO::FETCH_ASSOC);
  }
}

Ako je vidieť, okrem otvorenia databázy som si vyrobil 3 metódy:

  • query(), ktorá vracia len počet ovplyvnených riadkov v DB
  • queryOne(), ktorá vracia prvý záznam, na ktorý narazí
  • queryAll(), ktorá vracia kompletné výsledok dotazu

V mojej aplikácii síce budem potrebovať len jednu z nich, ale tie zvyšné sa nám iste budú hodiť v niektorom z ďalších pokračovaní tohto seriálu. Ak by niekomu nejaká metóda chýbala, môže si ju dopísať. Chýba tu napríklad iterátor pre vyberanie výsledkov dotazu. Ak však nepotrebujeme získavať z tabuľky státisíce riadok, chýbať nám nebude.

Prvým parametrom je SQL dotaz. Druhý parameter je nepovinný a slúži na odovzdávanie dát pomocou tzv. Parametrizovaných otázok. Je to vynikajúca vlastnosť ovládačov MySQLi a PDO. Pôvodný ovládač túto vlastnosť nemá, preto je nutné dáta od užívateľov ošetriť funkcií mysql_real_escape_string(). PDO túto barličku nepotrebuje, dáta je možné odovzdávať priamo. Nespornou výhodou je, že dĺžka vkladaných dát sa nezapočítava do limitu dĺžky SQL dotazu. To iste ocenia najmä tí, ktorí radi do databázy ukladajú fotky či videá. V našom príklade druhý parameter zatiaľ nebude použitý.

<?php
// soubor Adresar.class.php

class Adresar{
  private $seznam;

  function __construct($spojeni){
    $this->seznam=$spojeni->queryAll("SELECT * FROM adresar");
    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;
  }
}

Trieda Adresar doznala len kozmetické zmeny. Zjednodušil sa konštruktor a volanie SQL dotazu. Presenter je stále rovnaký.

Zostáva už len hlavný modul, ktorý nazvem jednoducho index.php. Musím mu nejako vysvetliť, aby si natiahol potrebné moduly a pracoval s nimi. K tomu slúži príkaz include():

include('MyDB.class.php');
include('Adresar.class.php');

Lenže dnes už sa to tak nerobí, pretože u väčších projektov by mohlo byť dosť pracné a neprehľadné starať sa o natiahnutie všetkých modulov. Našťastie si môžeme v PHP nadefinovať funkcii so špeciálnym názvom __autoload(), ktorá to urobí za nás zakaždým, keď budeme chcieť nejakú triedu použiť.

<?php
// soubor index.php

function __autoload($class){
  include($class.'.class.php');
}

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

Teraz je už aplikácia hotová. Je síce trochu dlhšie, než bola pôvodne, ale získali sme modulárnosť. Databázu môžeme použiť aj na iný účel so zjednodušeným ovládaním. Triede Adresár môžeme podstrčiť inú databázu alebo iný zdroj dát. Ak budeme potrebovať inú vlastnosť databázy, jednoducho ju do triedy pridáme ako ďalšiu metódu.

Javí sa niekomu výsledný kód príliš komplikovaný? Aj to je možné. Úplne prvý príklad robil prakticky to isté a mal len 14 riadok. Lenže vypísanie tabuľky je veľmi primitívne úloha. U bežných aplikácií by sme veľmi rýchlo stratili prehľad a zhoršila by sa udržiavateľnosť kódu.

Nabudúce si urobíme trochu zložitejšie príklad a vysvetlíme si záhadnú skratku CRUD.


 

Všechny články v sekci
Ostatné tutoriály v PHP
Článek pro vás napsal Kit
Avatar
Uživatelské hodnocení:
Ještě nikdo nehodnotil, buď první!
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