Lekce 10 - Skládání stránek v PHP
V předchozím kvízu, Kvíz - Podmínky, boolean, switch a formuláře v PHP, jsme si ověřili nabyté zkušenosti z předchozích lekcí.
Dnes se v PHP tutoriálu podíváme na dynamické skládání stránek.
Dynamické skládání stránek
Většina dnešních webových stránek se skládá vlastně ze 2 částí:
- Tou první je tzv. layout, neboli rozložení webu. To je na každé podstránce webu stejné a obvykle obsahuje logo webu, navigační menu a patičku.
- Druhá část stránky je potom samotný článek, který je do layoutu zobrazen.
U statických webových stránek jsme do každé podstránky museli layout ručně zkopírovat (v minulosti se daly používat rámce, ale ty byly z HTML kvůli četným problémům odebrány). Mít v každé podstránce celý layout je samozřejmě nepřehledné, pracně se tam vkládá a hlavně je problém v layoutu potom něco změnit, změnu musíme udělat ve všech podstránkách.
Jelikož nyní známe PHP, není nejmenší problém v tom, aby obsah
článku do layoutu vložilo za nás. Na webu budeme mít v jednotlivých
souborech pouze podstránky (bez layoutu) a layout bude přítomný v souboru
index.php
. Zde do layoutu vložíme ten článek, který uživatel
vyžaduje. Uživatel si o článek řekne metodou GET
, vloží tedy
jméno stránky do URL adresy.
Můžeme si to představit takto:
Způsoby skládání stránek
Stránky můžeme skládat vlastně dvěma způsoby. Buď jak jsme si uvedli výše, že do layoutu vkládáme podstránku, nebo můžeme do podstránky vložit nahoru hlavičku a dolů patičku. My si zde ukážeme vkládání podstránky do layoutu, jelikož tento princip se dále používá i pro vkládání článků z databáze.
Příprava souborů
Založme si nový projekt a připravme si potřebné soubory. Budeme
potřebovat index.php
, ve kterém se bude nacházet náš layout.
Já jsem níže uvedený layout převzal ze zdejšího HTML seriálu, můžete si ho
odtamtud vypůjčit a stáhnout i potřebný styl a obrázky. Nebo si prostě
napište svůj, bohatě stačí, když tam bude nadpis
<!DOCTYPE html> <html lang="cs"> <head> <meta charset="utf-8" /> <meta name="description" content="Osobní portfolio programátora HoBiho." /> <meta name="keywords" content="portfolio, programátor, HoBi" /> <meta name="author" content="HoBi" /> <link rel="shortcut icon" href="obrazky/ikona.ico" /> <link rel="stylesheet" href="styl.css" type="text/css" /> <link rel="stylesheet" href="css/lightbox.min.css" type="text/css" media="screen" /> <!-- Zde vložíme ještě skripty z referencí, ať funguje lightbox --> <script src="js/lightbox-plus-jquery.min.js"></script> <script src="js/lightbox.min.js"></script> <title>Moje první webová stránka</title> </head> <body> <header> <div id="logo"> <h1>Honza<span>Bittner</span></h1> <small>webdeveloper</small> </div> <nav> <ul> <li><a href="index.php?stranka=domu">Domů</a></li> <li><a href="index.php?stranka=omne">O mně</a></li> <li><a href="index.php?stranka=dovednosti">Dovednosti</a></li> <li><a href="index.php?stranka=reference">Reference</a></li> <li><a href="index.php?stranka=kontakt">Kontakt</a></li> </ul> </nav> </header> <article> <header> <h1>O mně</h1> </header> <section> <?php ?> </section> <div class="cistic"></div> </article> <footer> Vytvořil ©HoBi 2021 pro <a href="http://itnetwork.cz">itnetwork.cz</a> </footer> </body> </html>
V layoutu máme nějakou HTML hlavičku, dále hlavičku webové stránky, ve které je logo a navigace. Všimněte si, že odkazy na podstránky směřují na adresu:
index.php?stranka=domu
Všechny odkazy tedy vedou na soubor s layoutem, kterému předávají v
parametru název stránky, která se do něj má vložit. Tyto HTML
stránky si vložíme do podsložky podstranky/
se stejným názvem
a příponou .php
. Podstránka omne tedy bude uložena
v:
podstranky/omne.php
Podstránky by teoreticky mohly mít i příponu HTML, ale často v některé budeme chtít nějaký PHP skript, např. pro kontaktní formulář.
Všimněte si také prázdné PHP sekvence v elementu
<section>
. Přesně tam budeme podstránku vkládat.
Vytvořte si složku podstranky/
a několik takových
podstránek s příponou .php
.
Vložení souboru
PHP má víceméně dva způsoby, jak do nějakého skriptu vložit obsah jiného souboru.
Vložení textu
Pokud chceme obsah cizího souboru vložit jako text, slouží k tomu PHP
funkce file_get_contents()
. Funkce bere v parametru cestu k souboru
a vrací text, který soubor obsahuje.
Obsah podstránky bychom pomocí funkce vložili kódem níže:
// skript níže není bezpečný $obsah = file_get_contents('podstranky/' . $_GET['stranka'] . '.html'); echo $obsah;
Kód není ještě bezpečný, což dořešíme na konci lekce.
Všimněte si, že jsem dal podstránkám příponu .html
. Pokud
bychom měli v podstránce totiž PHP skript a vložili ho touto funkci do
layoutu, vypsal by se zdrojový kód skriptu místo toho, aby se provedl. To
může být dost nebezpečné, jelikož PHP skripty běžně obsahují
přístupové údaje k databázi a další citlivá data. Pokud však chceme
vložit nějaké HTML nebo prostý text z nějakého souboru, je funkce
ideální.
Dalším bezpečnostním problémem je, že uživatel si může do parametru napsat co chce a vypisovat si tak i obsah stránek, které ukazovat nechceme.
Vložení skriptu
Pokud chceme, aby se obsah cizího souboru vykonal jako PHP skript,
použijeme k tomu funkci require()
. Funkce bere jako parametr opět
cestu k souboru a obsah hned vypíše. Pokud je v souboru nějaká PHP sekvence,
tak ji spustí.
Do PHP sekvence v index.php
vložíme následující kód:
// skript níže není bezpečný require('podstranky/' . $_GET['stranka'] . '.php');
A vyzkoušíme zadat adresu nějaké podstránky:
Můžete si zkusit proklikat menu, podstránka se vždy vloží do layoutu a celý web se vypíše v prohlížeči. Velmi jsme si zjednodušili práci a otevřeli cestu do budoucna, kdy texty budeme vkládat z databáze.
Kromě funkce require()
nalezneme v PHP i funkci
include()
. Ta funguje úplně stejně, jen při neúspěšném
vložení nezastaví běh aplikace, ale pouze vyvolá warning.
Bezpečnost
POZOR! Obě výše zmíněné funkce jsou potenciálně velmi nebezpečné a pokud je špatně použijete, vznikne vám v aplikaci bezpečnostní díra.
Podstata problému je v tom, že zobrazujeme obsah nějakého souboru, jehož
název zadává uživatel. Ten tak může načíst např. soubor
.htpasswd
, ve kterém jsou uložena hesla a to touto adresou:
http://vasestranka.cz/index.php?stranka=../.htpasswd
Sekvence ../
přesune o složku výše. Dostaneme se tedy z
podstránek do kořenové složky s webem. Následně útočník může zobrazit
obsah úplně čehokoli.
Zabezpečení
Řešením této bezpečnostní trhliny je samozřejmě ošetřit vstup
uživatele tak, aby mohl obsahovat jen znaky a-z
a maximálně
čísla. To uděláme pomocí tzv. regulárního výrazu. Teorie okolo těchto
výrazů je poměrně složitá, ale jednoduše řečeno se jedná o takový
"minijazyk" (správně metajazyk), který slouží zejména pro kontrolu obsahu
textových řetězců. V dalších kurzech na síti se jim ještě budeme
věnovat, nyní nám musí stačit, že k ověření řetězce pomocí
regulárního výrazu slouží PHP funkce preg_match()
, která
vrátí 1
pokud text odpovídá.
Rovnou i změníme funkci require()
na include()
a
pokud se vložení nepovede, zobrazíme chybovou hlášku. U funkce
require()
se takto ptát nemůžeme, při neúspěchu vždy
zastaví aplikaci. Také přidáme podmínku, že pokud parametr není zadaný,
zobrazí se podstránka domů.
V následující ukázce použijeme stříšku ^
.
Na české klávesnici ji píšeme pomocí Pravého ALT a klávesy
š
:
Náš kód vypadá takto:
if (isset($_GET['stranka'])) $stranka = $_GET['stranka']; else $stranka = 'domu'; if (preg_match('/^[a-z0-9]+$/', $stranka)) { $vlozeno = include('podstranky/' . $stranka . '.php'); if (!$vlozeno) echo('Podstránka nenalezena'); } else echo('Neplatný parametr.');
Web je nyní bezpečný a vás již nebrzdí ruční kopírování layoutu. Můžete si zkusit vložit jako podstránku náš kontaktní formulář.
Nad otázkou bezpečnosti bychom se u webových aplikací měli zamýšlet vždy, když uživatel někde něco zadává. Vždy se musíme zeptat, co se s touto hodnotou děje a zda nemůže nějaký vstup způsobit bezpečnostní chybu.
Hotový web je v příloze ke stažení.
V příští lekci, Cykly for a while v PHP, se podíváme na cykly.
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 4599x (2.71 MB)
Aplikace je včetně zdrojových kódů v jazyce PHP