Black Friday Black Friday
Black Friday výprodej! Až 80 % extra bodů zdarma! Více informací zde

Lekce 8 - Výpis článků z databáze v PHP (MVC)

PHP MVC Výpis článků z databáze v PHP (MVC) American English version English version

ONEbit hosting Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

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.

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($url)
        {
                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()
        {
                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ě podle ID, 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($parametry)
        {
                // 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:

Úvod
localhost/cla­nek/uvod

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á., 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.

Pozn.: 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($parametry)
{
        // 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:

Your page
localhost/clanek/

V příští lekci, Zabezpečení šablon, se budeme věnovat zabezpečení šablon proti XSS.


 

Stáhnout

Staženo 1288x (13.19 kB)
Aplikace je včetně zdrojových kódů v jazyce PHP

 

 

Článek pro vás napsal David Čápka
Avatar
Jak se ti líbí článek?
28 hlasů
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor sítě se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.
Miniatura
Předchozí článek
Databázový wrapper
Miniatura
Následující článek
Zabezpečení šablon
Aktivity (7)

 

 

Komentáře
Zobrazit starší komentáře (39)

Avatar
Libor Sitek
Člen
Avatar
Libor Sitek:16.8.2017 13:46

Jen jsem si všiml drobné chyby v ukázce kódu u třídy ClanekKontroler, kde se nastavuje hlavička stránky:

'popis' => $clanek['popis']

Správně tam má být:

'popis' => $clanek['popisek']
Odpovědět  +1 16.8.2017 13:46
Když se chce, hledá se jak, když se nechce, hledá se proč
Avatar
arnost99
Člen
Avatar
arnost99:30.11.2017 23:00

Chtěl bych se zeptat, jestli je možné udělat model - např spavce.php, který bude mít funkce typu vytvoř, ulož, smaž atp (ty, které se mohou opakovat, v případě rozšíření systému - vytvoření článku, uživatele... smazání článku, uživatele) a další správce - např SpravceClanku.php, SpravceSouboru.php a další - které by byly .... extends Spravce - tím bych pak odkazoval pouze na jednu třídu správce a celou věc si zjednodušil - nebo je to z bespečnostního hlediska rizikové a je lepší ty třídy oddělit? A případně proč? Díky

 
Odpovědět 30.11.2017 23:00
Avatar
stitch123
Člen
Avatar
stitch123:11.12.2017 21:49

Zdravím!

Z nějakýho důvodu mi nefunguje propojení s databází.

Od té doby, co jsem přidal model Db.php, se místo úvodní stránky zobrazuje prostě
Fatal error: in C:\xampp\htdoc­s\modely\Db.php on line 21

Nic dalšího.

Stejnej problém mám i se zdrojáky od autora. Mohl by být problém v připojovacím příkazu v index.php?

Db::pripoj("student.sspbrno.cz", "1409011296", "heslo", "1409011296");

Heslo samozřejmě změněno.

Tady jsou celý zdrojáky:

Db.php
https://www.itnetwork.cz/dev-lighter/996

index.php
https://www.itnetwork.cz/dev-lighter/997

Editováno 11.12.2017 21:49
 
Odpovědět 11.12.2017 21:49
Avatar
stitch123
Člen
Avatar
Odpovídá na stitch123
stitch123:26.12.2017 23:00

Vyřešeno! Měl jsem překlep v názvu tabulky... :-X

 
Odpovědět 26.12.2017 23:00
Avatar
Katka Zimmermannova:5. května 16:08

Zdravím :) Mohla bych se prosím zeptat, jak takto vytvořené (vygenerované) texty z databáze doplním o obrázky? Dá se to nějak jednoduše udělat?

 
Odpovědět 5. května 16:08
Avatar
Honza Bittner
Šupák
Avatar
Odpovídá na Katka Zimmermannova
Honza Bittner:5. května 19:10

Budeš si třeba ukládat url adresu obrázků a pomocí toho vygeneruješ <img>.

Odpovědět 5. května 19:10
Milovník Dartu. Student FIT ČVUT. Sleduj mě na https://twitter.com/tenhobi a ptej se na cokoli na https://github.com/...
Avatar
Miroslav Mucha:14. června 13:07

Ahoj, trochu mě mate, proč je v obecném kontroleru definována metoda zpracuj($para­metry), která žádnou akci nevykonává, když pak každý další kontroler má svou vlastní metodu zpracuj(). Zkusil jsem ji v obecném kontroleru zakomentovat a aplikace funguje stále stejně.
Díky za odpověď.

 
Odpovědět 14. června 13:07
Avatar
Odpovídá na Miroslav Mucha
Denis Ťažký:14. června 15:09

Táto funkcia spracováva url adresu čo požaduješ, napr budeš mat kontroler abcdKontroler url dáš http://tvojweb.sk/abcd/bla a bla sa ti zavolá do sekcie zpracuj a tam si už robíš podľa seba , napr môžeš spraviť viac webov na jeden kontroler

 
Odpovědět 14. června 15:09
Avatar
Pavel Mach
Člen
Avatar
Pavel Mach:1. července 22:25

zajímala by mě možnost stránkování u výpisu článků, jak to efektivně přidat, vůbec mě nenapadá co napsat do kontroleru co do modelu a do pohledu. Poradí mi prosím někdo, díky :)

 
Odpovědět 1. července 22:25
Avatar
Bohuslav Holček:20. července 11:54

pekni tutorial, popravde sem jej uplne nedooncil, ale zacal jsem pracovat s http://www.tinymvc.com/
a jako sablonovaci system smarty

nemusel sem si tak psat celi system, pouzivam system ktery jiz je napsani ale je minimalisticky.
clovek se na tom rychle nauci MVCmodel a zacne si psat moduly a controllery cii views, podle toho co se mu hodi.
casem sem se vratim abych se kouknul na slozitejsi konstrukce.
Ono na 90% prace to staci, co uz bude tech 10 % to se bdu ucit dal. ae na tech 90% si to clovek pekne procvici.
odporucam zacatecnikum jako jsem ja zacit s tinymvc a smarty dohromady. rychle to roste... hlavne k tinymvc je rozsahle forum, takze clovek si najde co je potreba.

 
Odpovědět 20. července 11:54
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 49. Zobrazit vše