MySQLi (objektově)
Rozšíření PHP MySQL - základní rozšíření umožňující práci s MySQL. Doporučuje se ho používat pouze do verze MySQL 4.1.3. I když je funkční i u novějších verzí, neumožňuje využití nových možností MySQL. Rozšíření PHP MySQLi (MySQL Improved) - rozšíření vyvinuté pro MySQL 4.1.3 a novější. Umožňuje přístup k novým funkcím. Součástí PHP je od verze 5. MySQLi podporuje jak objektově orientovaný, tak i procedurální styl programování.
1. Vytvoření instance třídy mysqli Nejprve vytvoříme novou instanci třídy mysqli a konstruktoru můžeme předat informace potřebné k připojení a výběru databáze. Tím ušetříme několik řádků kódu, ale kvůli větší přehlednosti můžeme volat konstruktor bez parametrů a patřičné hodnoty předat do metod pro připojení ($mysqli -> connect) a výběr databáze ($mysqli ->select_db). Příklad vytvoření instance třídy včetně parametrů pro připojení: $mysqli = new mysqli('localhost', 'login', 'heslo', 'databaze');
1.1. Připojení k serveru mysql Pokud jsme nepředali parametry pro připojení k serveru do konstruktoru, je potřeba zavolat metodu $mysqli -> connect Příklad: $mysqli = new mysqli(); $mysqli -> connect ('localhost', 'login', 'heslo', 'databaze');
1.2. Výběr databáze mysql Pokud se potřebujeme připojit k více databázím, nebo jsme nezadali název databáze do konstruktoru při vytváření třídy nebo metody $mysqli -> connect, můžeme použít metodu $mysqli ->select_db Příklad: $mysqli -> select_db ('databaze');
1.3. Zprávy o chybách připojení Při práci s databázemi, může dojít k neočekávaným závadám. Rozšíření mysqli obsahuje dvě metody, které nám můžou poskytnout informace o chybě: $mysqli->connect_error a $mysqli->connect_errno. (u objektově orientované alternativy, se dá použít až od verze PHP 5.3.0) $mysqli->connect_error $mysqli->connect_errno
vrací chybovou zprávu odpovídající povaze vzniklé chyby vrací číselný kód odpovídající chybové zprávy
1
Příklad: $mysqli = @new mysqli('localhost', 'chybny_login', 'heslo', 'databaze'); if ($mysqli->connect_error) { die('Při připojení došlo k chybě: ' . $mysqli->connect_error . '. Číslo chyby: ' . $mysqli->connect_errno); }
Výsledek v prohlížeči: Při připojení došlo k chybě: Access denied for user 'fake_user'@'localhost' (using password: YES). Číslo chyby: 1045
1.4. Uzavření připojení Jakmile nějaký skript skončí své vykonávání, automaticky se uzavřou všechna otevřená databázová připojení a zotaví se prostředky. Pokud ale bude nějaká stránka požadovat připojování k více databázím, mělo by se každé připojení uzavírat. Pokud se ale používá jen jediné připojení, je dobrým zvykem jej také na konci skriptu uzavřít. Připojení se uzavírá metodou $mysqli -> close. Příklad: $mysqli->close();
Metoda uzavře dříve otevřené databázové připojení. Vrátí TRUE, pokud bude uspěšná, jinak vrátí FALSE.
2. Dotazy 2.1. Vykonání dotazu Jakýkoliv druh interakce s databází se děje přes nějaký dotaz. Pro zasílání dotazů databázi slouží metoda $mysqli->query, která má jeden povinný a jeden nepovinný parametr. Povinným parametrem je SQL dotaz, který lze zapsat buď pomocí proměnné, nebo přímo do metody. Příklad1: $query = "SELECT Name FROM City"; $result = $mysqli->query($query);
Příklad2: $result = $mysqli->query("SELECT Name FROM City");
Nepovinným parametrem se modifikuje chování metody: MYSQLI_STORE_RESULT: vrátí výsledky jako bufferovanou sadu, což znamená, že celá sada bude pro navigaci dostupná najednou. Je to výchozí nastavení. MYSQLI_USE_RESULT: vrátí výsledky jako nebufferovanou sadu, což znamená, že se sada bude získávat ze serveru postupně na základě potřeb. Příklad3: $result = $mysqli->query("SELECT Name FROM City", MYSQLI_USE_RESULT);
2
2.2. Zotavení paměti dotazu V situacích, kdy se získávají rozsáhlé sady výsledků, by se měla zotavit paměť jakmile se se sadou skončí. K tomu slouží metoda $mysqli->free_result. Příklad: $mysqli = @new mysqli('localhost', 'login', 'heslo', 'databaze'); if ($mysqli->connect_error) { die('Při připojení došlo k chybě: ' . $mysqli->connect_error . '. Číslo chyby: ' . $mysqli->connect_errno); } $result = $mysqli->query("SELECT Name FROM City", MYSQLI_USE_RESULT); // Něco se provede se sadou výsledků $result->free();
// Zotaví se prostředky dotazu
2.3. Příprava sady výsledků ke zpracování Původní rozšíření mysql PHP umožňovalo vykonávat dotazy a vracet sady výsledků buď jako bufferované (mysql_query()) nebo nebufferované (mysql_unbuffered_query()). Toto chování je k dispozici i v mysqli. Požadovaný typ výsledků můžeme deklarovat buď výše uvedenou metodou $mysqli->query a nastavením parametru, nebo pomocí metody $mysqli->real_query v součinnosti s $mysqli->store_result nebo $mysqli->use_result. Příklad: $query = "SELECT Name FROM City"; $mysqli->real_query($query); $result = $mysqli->store_result();
Metoda $mysqli->query je s metodou $mysqli->real_query identická, jen s tím rozdílem, že u metody $mysqli->real_query není možné určit typ vrácené sady výsledků, takže je nutné navíc volat buď $mysqli->store_result nebo $mysqli->use_result.
3. Analýza výsledků Jakmile je vykonaný dotaz a je ke zpracování připravena sada výsledků, je potřeba analyzovat získané řádky. K tomu slouží několik metod, s nimiž se získávají sloupcové hodnoty uložené v jednotlivých řádcích. Která metoda se zvolí, záleží jen na uživateli, protože se liší jen způsob, jakým se odkazuje na sloupce.
3.1. Metoda mysqli_fetch_row() Tato metoda získá ze sady výsledků celý řádek a hodnoty umístí do indexovaného pole. Pro výpis dat lze například použít funkci list() a cyklus while, kdy se budou pro každý řádek hodnoty sloupců přiřazovat do proměnných.
3
Příklad: ...
metoda mysqli_fetch_row() s použitím funkce list() a cyklu while
$query = "SELECT productid, name, price FROM product ORDER BY name "; $result = $mysqli->query($query); while (list($product, $name, $price) = $result->fetch_row()) { echo "($productid) $name: $price
"; }
...
3.2. Metoda mysqli_fetch_array() Metoda mysqli_fetch_array() je jen rozšířená verze mysqli_fetch_row(). Pomocí nepovinného parametru lze ovlivnit chování metody:
MYSQLI_ASSOC: vrátí řádek jako asociativní pole, kde je klíčem název sloupce a hodnotou obsah sloupce. MYSQLI_NUM: vrátí řádek jako číselné indexované pole, pořadí je určeno pořadím názvů sloupců specifikovaných dotaze. Pokud se zvolí tato hodnota, bude pole fungovat stejně jako mysqli_fetch_row(). MYSQLI_BOTH: vrátí řádek jako asociativní pole i jako číselně indexované pole. Proto se na každý sloupec dá odkazovat jeho číselnou pozicí i název sloupce. Je to výchozí hodnota.
Příklad1: ...
sada výsledků získaná pomocí asociativních indexů
$query = "SELECT productid, name, price FROM product ORDER BY name"; $result = $mysqli->query($query); while ($row = $result->fetch_array(MYSQLI_ASSOC)) { $productid = $row[productid]; $name = $row[name]; $price = $row[price]; echo "($productid) $name: $price
"; }
... Příklad2: ...
sada výsledků získaná pomocí číselných indexů
$query = "SELECT productid, name, price FROM product ORDER BY name "; $result = $mysqli->query($query); while ($row = $result->fetch_array(MYSQLI_NUM)) { $productid = $row[0]; $name = $row[1]; $price = $row[2]; echo "($productid) $name: $price
"; }
...
4
3.3. Metoda mysqli_fetch_assoc() Metoda mysqli_fetch_assoc() pracuje stejně jako předchozí metoda mysqli_fetch_array(), když se v parametru zadá hodnota MYSQLI_ASSOC.
3.4. Metoda mysqli_fetch_object() Metoda mysqli_fetch_object() pracuje podobně jako metoda mysqli_fetch_array(), ale vrátí se objekt, nikoliv pole. Příklad: ...
sada výsledků získaná pomocí objektů
$query = "SELECT productid, name, price FROM product ORDER BY name "; $result = $mysqli->query($query); while ($row = $result->fetch_object()) { $productid = $row->productid; $name = $row->name; $price = $row->price; echo "($productid) $name: $price
"; }
...
4. Vykonání několika dotazů za sebou Rozšíření mysqli disponuje novou schopností, která umožňuje vykonat několik dotazů za sebou, a pak získávat jednotlivé sady tak, jak je to potřeba.
4.1. Metoda mysqli_multi_query() Metoda mysqli_multi_query() umí vykonat jeden dotaz, nebo několik dotazů za sebou, což dává možnost získat jednotlivé sady později.
4.2. Metoda mysqli_more_results() Metoda mysqli_more_results() určí, zda ještě zbývá nějaká sada výsledků v tom, co se vrátilo z volání metody mysqli_multi_query().
4.3. Metoda mysqli_multi_query() Metoda mysqli_next_results() získá další sadu výsledků z těch, které vrátila metoda mysqli_multi_query().
5. Připravené příkazy Běžně se stává , že se nějaký dotaz vykonává opakovaně, jen se při každé iteraci použijí jiné parametry. Když se to provádí konvenční metodou mysql_query() ve spojení s mechanizmem cyklu, znamená to nejen dost zbytečné zátěže navíc, protože se musí opakovaně analyzovat platnost téměř identického dotazu, ale je to i dost nepohodlné z hlediska psaní kódu, protože je třeba při iteraci opakovaně překonfigurovávat dotaz pomocí nových hodnot. Aby se tedy daly lépe řešit záležitosti okolo opakovaně vykonávaných dotazů, byly zavedeny připravené příkazy.
5
K dispozici jsou dvě varianty: Vázané parametry: varianta s vázaným parametrem umožňuje uložit dotaz na server MySQL tak, že se opakovaně odesílá na server jen ta data, která se v každé iteraci mění a tam se integrují do dotazu, který se pak vykoná. Pokud např. vytvoříme nějakou webovou aplikaci, přes kterou vkládáme nějaké výrobky do databáze, vytvoříme formulář, do kterého půjde zadat současně až 10 výrobků (id, název, popis, cena). Protože se budou tyto informace vkládat pomocí identických dotazů (údaje ale budou pokaždé jiné), bylo by rozumné použít připravený příkaz s vázanými parametry. Vázané výsledky: varianta s vázanými výsledky umožňuje „nastrkat“ hodnoty ze sady výsledků do číselně indexovaného nebo asociovaného pole tak, že se sváží proměnné PHP s odpovídajícími sloupci, což by se jinak dělalo dost těžkopádně. Pak se dál pracuje s naplněnými proměnnými.
5.1. Metoda mysqli_stmt_prepare() Bez ohledu na to, zda se použije připravený příkaz vázaný na parametry nebo vázaný na výsledky, musí se nejprve připravit k vykonání metodou mysqli_stmt_prepare(). Příklad: $stmt->prepare($query);
5.2. Metoda mysqli_stmt_close() Jakmile se připravený příkaz přestane používat, dají se metodou mysqli_stmt_close() zotavit prostředky, které požadoval. Příklad: $stmt->close();
5.3. Metoda mysqli_stmt_execute() Jakmile je příkaz připravený, je potřeba ho vykonat. Kdy přesně se má příkaz vykonat, záleží na tom, zda pracujeme s vázanými parametry, nebo s vázanými výsledky. Budou-li to vázané parametry, vykonáme příkaz poté, co se parametry skutečně svážou metodou mysqli_stmt_bind_param(). Budou-li to vázané výsledky, vykonáme příkaz předtím, než vázat výsledky metodou mysqli_stmt_bind_result(). Příklad: $stmt->execute();
5.4. Metoda mysqli_stmt_bind_param() Používá-li se varianta připraveného příkazu s vázanými parametry, musí se použít metoda mysqli_stmt_bind_param(), aby se svázali názvy proměnných s odpovídajícími sloupci dotazu. Metoda obsahuje povinný parametr types, který reprezentuje datové typy proměnných, které následují tak, jak jsou zapsány v dotazu. Parametr se zapisuje proto, aby se
6
zajistilo co nejefektivnější zakódování dat, které se odesílají na server. Existují 4 dostupné kódy: i: všechny tyty integer d: tyty double a float b: typy blob s: všechny ostatní typy (včetně řetězců) Příklad: $stmt->bind_param(‘ssds’, $productid, $name, $price, $description);
5.5. Metoda mysqli_stmt_bind_result() Po připravení a vykonání dotazu, můžeme svázat proměnné na odpovídající získané sloupce pomocí metody mysqli_stmt_bind_result(). Příklad: $stmt->bind_result($productid, $name, $price, $description);
5.6. Metoda mysqli_stmt_fetch() Metoda mysqli_stmt_fetch() získá řádek z výsledků připraveného příkazu a přiřadí sloupce do svázaných výsledků. Příklad: … $query = "SELECT productid, name, price, description FROM product ORDER BY productid"; $stmt = $mysqli->stmt_init; $stmt->prepare($query); $stmt->execute(); $stmt->bind_result($productid, $name, $price, $description); while($stmt->fetch()) { echo "$productid, $name, $price, $description
"; } $stmt->close(); $mysqli->close();
…
5.7. Další metody Metoda $stmt->affected_rows
$stmt->free_result $stmt->num_rows $stmt->errno(mysqli_stmt stmt) $stmt->error(mysqli_stmt stmt)
Popis Vrací počet řádků, které ovlivnil naposled vydaný příkaz specifikovaný objektem stmt (je relevantní jen pro vkládací, aktualizační a odstraňovací dotazy). Zotaví paměť, kterou konzumoval příkaz specifikovaný objektem stmt. Vrací počet řádků, které získal příkaz specifikovaný objektem stmt. Vrátí chybový kód z naposled vydaného příkazu specifikovaného objektem stmt. Vrátí popis chyby z naposled vydaného příkazu specifikovaného objektem stmt. 7
Použitá literatura [1] Velká kniha PHP MySQL5, W. Jason Gilmore, Zoner Press, 2007 [2] http://programujte.com/?akce=clanek&cl=2009103100-php-a-mysql-mysqli-1-dil [3] http://www.php.net/manual/en/class.mysqli.php
8