Pokračování článku o rozšíření MySQLi. Tato část bude věnována především prepared statements a jejich použití v PHP.
Při práci s databází musíme vždy zvažovat bezpečnost a výkon. Pokud do SQL dotazů vkládáme data získaná od uživatele, je nutné ověřit tato data a v případě, že obsahují nebezpečné znaky, tak je ošetřit. Pokud zpracováváme větší množství dat, nebo posíláme databázi velký počet dotazů, musíme si dát pozor na paměťové a časové limity. MySQL od verze 4.1 umožňuje využívat tzv. prepared statements (dál jen PS), které nám tyto věci mohou usnadnit. V PHP lze PS využívat jen s pomocí rozšíření MySQLi.
Prepared Statements
PS jsou nástroj, který nám umožní spustit opakovaně daný SQL příkaz s různými parametry. Umožňují nám oddělit logiku a data v SQL. Jednoduchý PS může vypadat např. takto:
SELECT * FROM users WHERE ID = ?
Otazník v dotazu zastupuje parametr, který budeme databázi předávat později.
Důvodů pro využití PS je hned několik. Z bezpečnostního hlediska je výhodné oddělení logiky od dat v SQL dotazu. Není třeba řešit ochranu před útoky typu SQL injection, protože parametry předávané dotazu nemohou být včleněny do logiky dotazu.
Druhým přínosem PS je zlepšení výkonosti, k čemuž dojde ze dvou hlavních důvodů. Pokud voláme stejný dotaz opakovaně, pouze s různými parametry, tak oceníme nutnost parsovat dotaz pouze při prvním použití, při dalších dotazech se bude již používat předpřipravená verze. Druhou výkonnostní výhodou PS je využívání nového binárního protokolu pro přenos dat mezi klientem a serverem. Tradiční protokol nejprve všechna data zkonvertuje na string, odešle je a na serveru dochází ke zpětné konverzi na původní datový typ. Tím dojde ke zpomalení přenosu a nárustu velikosti předávaných dat. Binární protokol posílá všechna data v binární podobě.
PS je možné využít v SQL dotazech typu INSERT, REPLACE, UPDATE, DELETE, CREATE TABLE a SELECT.
Příklady použití PS v PHP
PHP pro vytvoření PS používá metodu mysqli::prepare(), jejímž jediným parametrem je SQL příkaz. Její použití si můžeme ukázat na jednoduchém příkladu.
prepare('SELECT `ID`, `Login`, `Prava`
FROM `uzivatele`
WHERE `Jmeno` = ?');
//Potom mu předáme parametr(y) pomocí metody bind_param()
//První parametr metody definuje datový typ jednotlivých proměnných
//s = string
$stmt->bind_param('s', $jmeno);
//Nakonec zavoláme metodu execute(), která dotaz odešle do databáze
$stmt->execute();
//Databáze přijala a zpracovala dotaz, jak se ale dostaneme k výsledkům?
//Nejprve musíme pomocí metody bind_result()
//propojit jednotlivé sloupce výsledku s PHP proměnnou
$stmt->bind_result($id, $login, $prava);
//Metoda fetch() tyto proměnné naplní daty z aktuálního řádku výsledku
while ($stmt->fetch())
{
echo 'Uživatel s identifikátorem ' . $id . ' má login ' . $login .
' a oprávnění ' . $prava . '.';
}
//Posledním krokem je ukončení PS a uvolnění použitých zdrojů pomocí metody close()
$stmt->close();
?>
Pro nové projekty je určitě výhodnější využívat PS než klasický přístup k databázi. Jejich hlavní výhodou je kromě vyšší rychlosti i oddělení dat a logiky dotazu, a tím i zvýšení bezpečnosti aplikace. Jelikož nejde o žádnou novinku, dá se předpokládat, že je bude možno používat na většině webhostingů.