Už dlouhou dobu porůznu vyvíjím webové aplikace, malé, velké i podivné nebo neužitečné. V posledním roce jsem se hodně zaměřil na bezpečnost dat a aplikací, proto bych zde rád publikoval něco, co na internetu najdete všude možně. Hůř se to pak hledá v aktualizované formě a nejhůř v češtině. Vše co zde dále uvedu slouží jako příklad a je třeba ledasco dotáhnout (design aplikace nebo čistotu kódu neřeším, jde mi o principy a postupy).
Ale budu moc rád za každé upozornění nebo případný zlepšovák. Co pro Vás nyní mám?
Jak se v PHP bezpečně spojit s databází a pracovat s ní.
V první části bych rád upozornil na fakt, že spojení s MySQL pomocí modulu mysqli (volím mysqli, protože se jedná o nejuniverzálnější a nejaktuálnější způsob připojení PHP k databázi – viz. php.net) může být objektově orientované (OOP) a procedurální. Celé PHP se pomalými krůčky sune k OOP, já ale zatím přežívám na procedurálním přístupu.
Příklad, který zde uvádím, je tedy využití mysqli modulu v PHP k připojení k databázi MySQL.
Připojení k samotné databázi
Připojení k samotné databázi probíhá velice snadno pomocí následujícího PHP kódu:
$mysqli = new mysqli('adresa-sql.serveru','uzivatelske-jmeno','uzivatelske-heslo*','nazev-databaze'); if ($mysqli->connect_error) { die('Chyba : ('. $mysqli->connect_errno .') '. $mysqli->connect_error); }
V případě, že se nepovede spojit s databází, očekávejte chybové hlášení (pokud je máte v PHP zapnuty) s informací, co se nepovedlo.
SELECT – zobrazení dat z databáze
//Vysvětlivka 1 $archiv = "0"; //Vysvětlivka 2 $query = "SELECT id,nazev,hodnota FROM pokus1 WHERE smazano=?"; //následuje příprava dotazu $statement = $mysqli->prepare($query); //Vysvětlivka 3 $statement->bind_param('i', $archiv); //proveď dotaz $statement->execute(); //ulož výsledek dotazu (není nutné) $statement->store_result(); //z vybraných hodnot (z hodnot v dotazu, opět postupně tak jak jsou v dotazu) utvoř proměnné $statement->bind_result($id, $nazev, $hodnota); //zpracování záznamů while($statement->fetch()) { print '<p>'; print $id.': '; print $nazev.' / '; print $hodnota; print '</p>'; }
Vysvětlivky:
- pro demonstrační účely nastavuji proměnnou, kterou využiji v dotazu
- dotaz do SQL, všimněte si, že v klauzuli WHERE mám zadáno, že požaduji aby sloupec „smazano“ byl roven otazníku, otazník bude následně nahrazen proměnnou
- proces přípravy detekuje proměnné a ty je třeba programu vysvětlit, proces „vysvětlení“ má dvě části: v první části definujete jaký typ proměnné bude v příkazu (zástupné znaky : s = string, i = integer, d = double, b = blob) a po čárce (v druhé části) pak následuje výpis proměnných (opět v pořadí jako je v dotazu), které se mají doplnit
Výše vypsaný kód vypíše na jeden řádek data z databáze. Pokud chcete mít v dotazu více proměnných, kód bude vypadat takto:
$stav = "ok"; $mesto = "Praha"; $archivovano = 0; $query = "SELECT id,prodejce,suma FROM prodeje WHERE stav=? AND mesto=? AND archivovano=?"; $statement = $mysqli->prepare($query); $statement->bind_param('ssi', $stav, $mesto, $archivovano); $statement->execute(); $statement->store_result(); $statement->bind_result($id, $prodejce, $suma); print '<table>'; print '<tr colspan="3">Prodeje: '.$mesto.'</tr>'; print '<tr><th>ID záznamu</th><th>Jméno prodejce</th><th>Celkem prodal</th></tr>'; while($statement->fetch()) { print '<tr>'; print '<td>'.$id.'</td>'; print '<td>'.$prodejce.'</td>'; print '<td>'.$suma.' CZK</td>'; print '</tr>'; } print '</table>';
Z tabulky jsme vybrali výsledky všech prodejců z města „Praha“, kde indikátor záznamu je „ok“ a nejedná se o záznam archivovaný.
Krása „Prepared Statements“ spočívá v tom, že nemůže dojít k SQL Injection, tedy napadení webu tímto postupem. Všechny pokusy o injektáž SQL kódu budou zhaceny tím, že takto připravená proměnná již nebude akceptovat další SQL kód.
INSERT – vložení dat do databáze
Stačí upravit SQL dotaz a stejný kus kódu je použitelný i pro příkaz UPDATE nebo jiné přímé operace s tabulkami.
Vkládání dat do databáze probíhá už velmi podobně jako zobrazování, uvedu tedy přímo příklad.
$query = "INSERT INTO pokus1 (nazev,hodnota) VALUES(?, ?)"; $statement = $mysqli->prepare($query); $statement->bind_param('ss', $promenna, $hodnota); if($statement->execute()){ print 'Povedlo se! ID vloženého záznamu je : ' .$statement->insert_id .'<br />'; exit; }else{ die('Chyba : ('. $mysqli->errno .') '. $mysqli->error); }
Kód prostě vloží data do databáze nebo při selhání vypíše chybu.
Toto je krátká kuchařka pro základní připojení a dotazy do MySQL databáze pomocí PHP modulu mysqli. Připravuji ještě další článek o ochraně vstupů POST a GET, tedy při zpracování formulářů.
Budu moc rád za jakoukoliv zpětnou vazbu v komentářích.
One Response to PHP + MySQL, jak se bezpečně spojit a fungovat.