3. diel - Práca s MySQL v PHP - Použitie ovládača MySQLi
Tu je pokračovanie úvodného článku http://www.itnetwork.cz/...iho-ovladace
Tentokrát som použil novšie ovládač MySQLi. Bohužiaľ s ním veľa skúseností nemám, ale nemôžem ho ignorovať. V uvedenom príklade sa moc neprejaví jeho prednosti, ale snáď to nebude na škodu.
Najprv som sa pokúsil o klasický procedurálny kód. Výnimky sú však iba objektovej, preto 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 zrejmé, že sa táto procedurálne verzia príliš nelíši od predchádzajúcej verzie základného ovládača MySQL. Výhoda MySQLi sa prejaví až pri použití parametrizovaných dotazov a ďalších pokročilých funkcií. Tiež sa prejaví na výkone, lebo MySQLi je rýchlejší.
Teraz nasleduje pokus o objektové riešenie aplikácie. Snažil som sa priblížiť objektovému programovania, ako ho vidím v rôznych návodoch.
<?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"; }
Ako je vidieť, program sa mi trochu predĺžil. Ani sa mi v tejto podobe veľmi nepáči. Pokúsim sa teda prepísať ho do podoby, ktorá je mi bližšia:
<?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"; }
Ešte stále to nie je ono. SQL dotazy sú už oddelené od prezentácie v HTML, program je o niečo kratšia a snáď aj prehľadnejšie, ale testovanie návratovej hodnoty po každom volaní SQL dotazu nevyzerá práve ideálne. Výsledok jedného z otázok som ani netestoval, aj keď by som vlastne mal.
Hodilo by sa mi, keby sa po každej chybe pri práci s databázou automaticky vyhodila výnimka. Možno to v MySQLi nejako ide, ale rozumný návod som nenašiel. Riešenie som však objavil v ovládači PDO, o ktorom bude tretie pokračovanie tohto seriálu.