2. díl - Práce s MySQL v PHP - Použití ovladače MySQLi
Zde je pokračování úvodního článku http://www.devbook.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.


Tisk


