Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
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í.

Práce s MySQL v PHP - Použití ovladače MySQLi

Zde je pokračování úvodního článku http://www.itnetwork.cz/…iho-ovladace

Tentokrát jsem použil novejší ovladač MySQLi. Bohužel s ním mnoho zkušeností nemám, ale nemohu ho ignorovat. V uvedeném příkladu se moc neprojeví jeho přednosti, ale snad to nebude na škodu.

Nejprve jsem se pokusil o klasický procedurální kód. Výjimky jsou však pouze objektové, proto je ponechám.

<?php
try {
  $spojeni=@mysqli_connect("localhost","kit","","test");
  if (!$spojeni) {
    throw new Exception(mysqli_connect_error(), mysqli_connect_errno());
  }
  mysqli_query($spojeni,"SET NAMES utf8");
  $navrat=@mysqli_query($spojeni,"SELECT * FROM adresar");
  if(!$navrat) {
    throw new Exception(mysqli_stmt_error($navrat), mysqli_stmt_errno($navrat));
  }
  $row=mysqli_fetch_assoc($navrat);
  if(!isset($row)) {
    throw new Exception("Tabulka je prázdná");
  }
  echo("<table border=\"1\">\n");
  echo("<tr>\n");
  foreach($row as $key => $value) {
    echo("<th>".$key."</th>\n");
  }
  echo("</tr>\n");
  mysqli_data_seek($navrat,0);
  while ($row = mysqli_fetch_assoc($navrat)){
    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 patrné, že se tato procedurální verze příliš neliší od předchozí verze základního ovladače MySQL. Výhoda MySQLi se projeví až při použití parametrizovaných dotazů a dalších pokročilých funkcí. Také se projeví na výkonu, neboť MySQLi je rychlejší.

Nyní následuje pokus o objektové řešení aplikace. Snažil jsem se přiblížit objektovému programování, jak ho vidím v různých návodech.

<?php
class Adresar{

  private $spojeni;
  private $navrat;

  function __construct($host,$user,$pass,$name){
    $this->spojeni= @new mysqli($host,$user,$pass,$name);
    if ($this->spojeni->connect_error) {
      throw new Exception($this->spojeni->connect_error, $this->spojeni->connect_errno);
    }
    $this->spojeni->query("SET NAMES utf8");
  }

  function query($query) {
    $this->navrat=$this->spojeni->query($query);
    if(!$this->navrat) {
      throw new Exception($spojeni->error, $spojeni->errno);
    }
  }

  function getHeaders(){
    $row=$this->navrat->fetch_assoc();
    if(!isset($row)) {
      throw new Exception("Tabulka je prázdná");
    }
    return $row;
  }

  function getRows(){
    $rows=array();
    $this->navrat->data_seek(0);
    while ($row = $this->navrat->fetch_assoc()){
      $rows[]=$row;
    }
    return $rows;
  }
}

try{
  $db=new Adresar("localhost","kit","","test");
  $db->query("SELECT * FROM adresar");
  $row=$db->getHeaders();
  echo("<table border=\"1\">\n");
  echo("<tr>\n");
  foreach($row as $key => $value) {
    echo("<th>".$key."</th>\n");
  }
  echo("</tr>\n");
  foreach($db->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";
}

Jak je vidět, program se mi trochu prodloužil. Ani se mi v této podobě moc nelíbí. Pokusím se tedy přepsat ho do podoby, která je mi bližší:

<?php
class Adresar{

  private $spojeni;
  private $navrat;
  private $head;
  private $adr;

  function __construct($host,$user,$pass,$name){
    $this->spojeni= @new mysqli($host,$user,$pass,$name);
    if ($this->spojeni->connect_error) {
      throw new Exception($this->spojeni->connect_error, $this->spojeni->connect_errno);
    }
    $this->spojeni->query("SET NAMES utf8");
  }

  function precti() {
    $this->navrat=$this->spojeni->query("SELECT * FROM adresar");
    $this->head=$this->navrat->fetch_assoc();
    if(!isset($this->head)) {
      throw new Exception("Tabulka je prázdná");
    }
    $this->navrat->data_seek(0);
    if(!$this->navrat) {
      throw new Exception($spojeni->error, $spojeni->errno);
    }
    $this->adr=$this->navrat->fetch_all();
  }

  function __toString() {
    $headers='<tr><th>'.implode('</th><th>',array_keys($this->head)).'</th></tr>';
    $rows=array();
    foreach($this->adr 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");
  $adresar->precti();
  echo $adresar;
} catch(Exception $e) {
  echo "Tabulku nelze vypsat<br />\n";
  echo $e->getMessage(),"\n";
}

Ještě stále to není ono. SQL dotazy jsou již odděleny od prezentace v HTML, program je o něco kratší a snad i přehlednější, ale testování návratové hodnoty po každém volání SQL dotazu nevypadá právě ideálně. Výsledek jednoho z dotazů jsem ani netestoval, i když bych vlastně měl.

Hodilo by se mi, kdyby se po každé chybě při práci s databází automaticky vyhodila výjimka. Možná to v MySQLi nějak jde, ale rozumný návod jsem nenašel. Řešení jsem však objevil v ovladači PDO, o kterém bude třetí pokračování tohoto seriálu.


 

Všechny články v sekci
Zdrojákoviště pro OOP v PHP
Článek pro vás napsal Kit
Avatar
Uživatelské hodnocení:
2 hlasů
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