Lekce 8 - Výpis článků z databáze v PHP (MVC)
V minulé lekci, Databázový wrapper, jsme si vytvořili databázový wrapper nad PHP ovladačem PDO. Databázi máme již také připravenou, nic nám nebrání s ní komunikovat.
Dnes si přidáme ClanekKontroler
a naučíme aplikaci
zobrazovat článek a seznam článků z databáze.
Připojení
Jako první se musíme k databázi připojit. To provedeme v
index.php
, těsně před vytvořením směrovače:
// Připojení k databázi Db::pripoj("127.0.0.1", "root", "", "mvc_db");
Údaje si samozřejmě změňte podle svého webhostingu, takto jsou vyplněné pro localhost. Databázi máme v aplikaci přístupnou, pojďme se ji na něco zeptat.
Model - Správce článků
Vytvoříme třídu s logikou ohledně práce s články, která bude
obsahovat jednotlivé SQL dotazy. Třída bude samozřejmě v modelech a
jmenovat se bude SpravceClanku
. Pro každou databázovou entitu si
v našem systému vytvoříme nějakou podobnou třídu.
SpravceClanku
bude mít následující podobu:
<?php /** * Třída poskytuje metody pro správu článků v redakčním systému */ class SpravceClanku { /** * Vrátí článek z databáze podle jeho URL */ public function vratClanek(string $url): array { return Db::dotazJeden(' SELECT `clanky_id`, `titulek`, `obsah`, `url`, `popisek`, `klicova_slova` FROM `clanky` WHERE `url` = ? ', array($url)); } /** * Vrátí seznam článků v databázi */ public function vratClanky(): array { return Db::dotazVsechny(' SELECT `clanky_id`, `titulek`, `url`, `popisek` FROM `clanky` ORDER BY `clanky_id` DESC '); } }
Třída má celkem 2 metody:
vratClanek()
vrací jeden článek z databáze podle jeho URL. Získávání dat od uživatele není záležitost modelu, všimněte si, že URL mu jednoduše přijde v argumentu metody a neřeší odkud se vzalo. Do podmínky SQL dotazu proměnnou nevložíme přímo, ale místo její hodnoty vložíme zástupný znak (otazník). Všechny parametry SQL dotazu následně předáme databázi jako hodnoty v poli, ona si je do dotazu sama a bezpečně dosadí.vratClanky()
vrací seznam všech článků (bez jejich obsahu). Články jsou seřazené sestupně podleID
, tedy od nejnovějších po nejstarší. Všimněte si, že nevybíráme jejich obsah, metodu budeme používat pouze pro výpis seznamu.
Pohledy
Budeme potřebovat 2 pohledy. Jeden pro článek a druhý pro seznam článků.
clanek.phtml
U článku vypíšeme nadpis a potom jeho obsah. Pohled bude následující:
<header> <h1><?= $titulek ?></h1> </header> <section> <?= $obsah ?> </section>
Druhý pohled necháme na konec lekce.
Kontroler
Máme model, máme pohled, zbývá náš známý prostředník - kontroler,
který vše spojí dohromady. ClanekKontroler
bude mít
následující podobu:
class ClanekKontroler extends Kontroler { public function zpracuj(array $parametry): void { // Vytvoření instance modelu, který nám umožní pracovat s články $spravceClanku = new SpravceClanku(); // Získání článku podle URL $clanek = $spravceClanku->vratClanek($parametry[0]); // Pokud nebyl článek s danou URL nalezen, přesměrujeme na ChybaKontroler if (!$clanek) $this->presmeruj('chyba'); // Hlavička stránky $this->hlavicka = array( 'titulek' => $clanek['titulek'], 'klicova_slova' => $clanek['klicova_slova'], 'popis' => $clanek['popis'], ); // Naplnění proměnných pro šablonu $this->data['titulek'] = $clanek['titulek']; $this->data['obsah'] = $clanek['obsah']; // Nastavení šablony $this->pohled = 'clanek'; } }
Kontroler si vytvoří model a získá od něj článek podle URL adresy.
Pokud článek nebyl nalezený, vyhodnotí se proměnná s ním jako
false a přesměrujeme na ChybaKontroler
. Hlavičku
stránky nastavíme podle článku, dále pohledu předáme titulek a obsah, aby
článek mohl vypsat. Nakonec nastavíme pohled na
clanek.phtml
.
Pojďme si vše vyzkoušet. Když aplikaci zapneme, uvidíme vypsaný úvodní článek:
Můžete si zkusit zadat URL neexistujícího článku, budete přesměrování na chybovou stránku.
clanky.phtml
Seznam článků bude o něco složitější, protože potřebujeme vypsat jejich seznam z pole článků, které dostaneme od databáze. Jak že to ale uděláme, když zatím umíme vypisovat jen jednotlivé proměnné a zde potřebujeme vypsat obsah kolekce? Pojďme si rozšířit naše znalosti o PHP syntaxi, přesněji o šablonové verzi cyklů.
Šablonová syntaxe PHP
Kromě direktivy <?=
nám PHP nabízí šablonové
ekvivalenty nejběžnějších konstrukcí jazyka. Můžeme tak do pohledu
(šablony) vložit minimální část logiky, která nebude znepřehledňovat
HTML kód. Tyto šablonové ekvivalenty nám totiž umožňují vkládat PHP do
HTML.
Bez znalosti šablonové syntaxe PHP by výpis seznamu článků do tabulky vypadal asi takto:
<h1>Seznam článků</h1> <table> <?php foreach ($clanky as $clanek) { echo('<tr><td><h2> <a href="clanek/' . $clanek['url'] . '"> ' . $clanek['titulek'] . '</a> </h2>' . $clanek['popisek']); echo('</td></tr>'); } ?> </table>
HTML je nezvýrazněné, šablona nepřehledná a ztrácíme se v uvozovkách, jak řetězce spojujeme. Pojďme kód převést do šablonové verze:
<h1>Seznam článků</h1> <table> <?php foreach ($clanky as $clanek) : ?> <tr> <td> <h2><a href="clanek/<?= $clanek['url'] ?>"><?= $clanek['titulek'] ?></a></h2> <?= $clanek['popisek'] ?> </td> </tr> <?php endforeach ?> </table>
Všimněte si, že cyklus foreach
má za sebou napsanou
dvojtečku a potom se ukončí PHP direktiva. Toto je šablonová verze
foreach
, která pro každý prvek vyechuje HTML kód, který je
napsaný pod ním a to až do značky endforeach
. Podobně lze
přepsat i cykly for
a while
nebo podmínky
if
. HTML je zapsané jako HTML, ne jako string. Proměnné
vložíme do HTML pomocí <?=
, jak jsme zvyklí. Soubor
clanky.phtml
si s tímto obsahem ve složce pohledy vytvořte.
V šablonách stále neošetřujeme HTML entity a vystavujeme se tak útoku XSS. Napravíme to hned v příštím dílu.
Úprava ClanekKontroler
Seznam článků bude vypisovat ClanekKontroler
a to v
případě, když mu nezadáme žádný parametr. Kontroler jednoduše
podmínkou rozpůlíme na dvě části. Jedna vypisuje konkrétní článek a
druhá seznam. Pro tyto akce by se daly použít 2 kontrolery, ale obvykle se
zapisují do jednoho, když spolu úzce souvisí. Metodu zpracuj()
upravíme do následující podoby:
public function zpracuj(array $parametry): void { // Vytvoření instance modelu, který nám umožní pracovat s články $spravceClanku = new SpravceClanku(); // Je zadáno URL článku if (!empty($parametry[0])) { // Získání článku podle URL $clanek = $spravceClanku->vratClanek($parametry[0]); // Pokud nebyl článek s danou URL nalezen, přesměrujeme na ChybaKontroler if (!$clanek) $this->presmeruj('chyba'); // Hlavička stránky $this->hlavicka = array( 'titulek' => $clanek['titulek'], 'klicova_slova' => $clanek['klicova_slova'], 'popis' => $clanek['popisek'], ); // Naplnění proměnných pro šablonu $this->data['titulek'] = $clanek['titulek']; $this->data['obsah'] = $clanek['obsah']; // Nastavení šablony $this->pohled = 'clanek'; } else { // Není zadáno URL článku, vypíšeme všechny $clanky = $spravceClanku->vratClanky(); $this->data['clanky'] = $clanky; $this->pohled = 'clanky'; } }
Nyní přejděme na kontroler clanek a nezadáme URL článku, který se má zobrazit. Zobrazí se seznam všech článků na webu:
V příští lekci, Zabezpečení šablon, se budeme věnovat zabezpečení šablon proti XSS.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 1965x (15.08 kB)
Aplikace je včetně zdrojových kódů v jazyce PHP