IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

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ě 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(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:

Ú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á 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:

Seznam článků
localhost/clanek/

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 1931x (15.08 kB)
Aplikace je včetně zdrojových kódů v jazyce PHP

 

Předchozí článek
Databázový wrapper
Všechny články v sekci
MVC - Jednoduchý redakční systém v PHP objektově
Přeskočit článek
(nedoporučujeme)
Zabezpečení šablon
Článek pro vás napsal David Hartinger
Avatar
Uživatelské hodnocení:
135 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity