Získej svůj iPhone v nové soutěži! Získej svůj iPhone v nové soutěži!
Nová překladatelská soutěž ITnetwork.cz o telefon iPhone, sluchátka Beats a další věcné ceny za 4 hodiny práce.
Přidej si svou IT školu do profilu a najdi spolužáky zde na síti :)

10. díl - Skládání stránek v PHP

PHP Základní konstrukce Skládání stránek v PHP 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, Vylepšení kontaktního formuláře v PHP, jsme dokončili kontaktní emailový formulář. S formuláři umíme již slušně zacházet. 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.

Layout webových stránek

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:

Skládání webových stránek v PHP

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-cz">

        <head>
                <meta charset="utf-8" />
                <link rel="stylesheet" href="styl.css" type="text/css" />
                <title>HoBiho portfolio</title>
        </head>

        <body>
                <header>
                        <div id="logo"><h1>HoBi</h1></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>
                        <div id="centrovac">
                                <header>
                                        <h1>O mně</h1>
                                </header>

                                <section>
                                        <?php

                                        ?>
                                </section>
                                <div class="cistic"></div>
                        </div>
                </article>


                <footer>
                        Vytvořil &copy;HoBi 2013 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_conten­ts(). 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. Kód není ještě bezpečný, což dořešíme na konci lekce.

// skript níže není bezpečný
$obsah = file_get_contents('podstranky/' . $_GET['stranka'] . '.html');
echo $obsah;

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:

Skládání stránek v PHP

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.

Pozn.: Kromě 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 require na include a pokud se vložení nepovede, zobrazíme chybovou hlášku. U 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ů.

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. Brzy se také dostaneme k databázím.


 

Stáhnout

Staženo 2708x (1.09 MB)
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?
40 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 se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.
Miniatura
Všechny články v sekci
Základní konstrukce jazyka PHP
Miniatura
Následující článek
Cykly for a while v PHP
Aktivity (6)

 

 

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

Avatar
Filip (animátor/programator):10. dubna 20:18

Ďakujem ti za odpoveď mal si pravdu už som to opravil prepáč že som položil takú hlúpu otázku ale bolo 7 ráno a ja som bol už unavený z kódovania ......
Proste som si to nevšimol :D
MOJA CHYBA!

Odpovědět 10. dubna 20:18
Nikdy sa nevzdávaj a choď si za svojim snom.......
Avatar
Martin Bubník:24. června 12:00

Potřeboval bych poradit.. Kód mám uplně stejný jako vy, ale hází mi to chybu..
<section>
<?php
if (isset($_GET["s­tranka"]))
$stranka = $_GET["stranka"];
else
$stranka = 'domu';
if (preg_match("/^[a-z0-9]+$/", $stranka))
{
$vlozeno = include("podstran­ky/" .$stranka . ".php");
if (!$vlozeno)
echo("Podstránka nenalezena");
}
else
echo("Neplatný parametr.");
?>
</section>

V té sekci, kde $vlozeno = include("podstran­ky/" .$stranka . ".php"); tak mi háže chybu:

Warning: include(podstran­ky/domu.php) [function.include]: failed to open stream: No such file or directory in /var/www/html­/bubnima16/We­by/Cviceni/skl_stra­nek/index.php on line 42

Warning: include() [function.include]: Failed opening 'podstranky/do­mu.php' for inclusion (include_path='­.:/usr/share/pe­ar:/usr/share/php') in /var/www/html­/bubnima16/We­by/Cviceni/skl_stra­nek/index.php on line 42

Editováno 24. června 12:02
 
Odpovědět 24. června 12:00
Avatar
Martin Bubník:24. června 12:00

Poradí prosím někdo??

 
Odpovědět 24. června 12:00
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Martin Bubník
David Čápka:24. června 12:02

A s čím chceš poradit? Máš tam jasně napsané, že nemůže najít soubor "podstranky/do­mu.php", takže ho tam asi nemáš.

Odpovědět  +1 24. června 12:02
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Odpovídá na David Čápka
Martin Bubník:24. června 12:07

Klasika.. Trocha nepozornosti a člověk neví.. A při tom je to hloupost.. to bude tím vedrem %P
Moc děkuji za radu.. A mimochodem, vaše tutoriály a celkově učení script. jazyka php od začátku je super, zatím zvládám všechno, tady jsem samozřejmě zatím skončil, snažím se si to svými nápady trochu zlepšit atd a celkově,.. Moc mi to pomáhá

 
Odpovědět  +1 24. června 12:07
Avatar
maxijoey
Člen
Avatar
maxijoey:23. listopadu 18:32

Ahoj, tak nějak si s tím PHP hraju a jedne věci nerozumím. Nějak mi to nejde na mozek. Jde mi o tvorbu nové stránky.
Modelvě. Budu tvořit kategorie eshopu dynamicky,to je mám rozhraní v php na to. Umím si do databáze přes něj nebo někam nahrát parametry nové stránky, název, url, popis atd... Umím je i přečíst. Ale kde se ta nová stránka vezme? jak ji vytvořím?

 
Odpovědět 23. listopadu 18:32
Avatar
Odpovídá na maxijoey
Matyáš Máslík:23. listopadu 23:38

Doufám, že to co zde napíšu nebude úplná kravina, ale alespoň takhle jsem to z nastudovaných materiálů pochopil já :D

Ty novou stránku vlastně netvoříš, ale vkládáš obsah do té původní. Ta "původní" je tvoje hlavní stránka s vytvořeným layoutem (který tedy bude pro všechny stejný), do kterého vkládáš předpřipravený obsah. Ten obsah, který má být vložený si uživatel logicky vyžádá podle nějakého naskriptovaného menu :)

Jinak nevím, jestli je zrovna moudré pouštět se rovnou do e-shopu, pokud jsi narazil na problém již zde. Mohla by se tam vyskytnout nějaká vážná chyba, která by tě mohla stát hodně peněz :D Není to myšleno nijak zle, samozřejmě ani neznám tvoje skutečné schopnosti. Ale prostě pozor na to :) A pro příště by nebylo od věci založit na to vlákno na fóru, takhle ti málokdo odpoví a potrvá to většinou dost dlouho.

 
Odpovědět 23. listopadu 23:38
Avatar
Tomáš Pour
Člen
Avatar
Tomáš Pour:26. listopadu 10:35

Ahoj, mám takový problém...do podstránek se mi v pohodě vloží layout, ale ikdyž mám v podstránce nějaký obsah, tak se mi zobrazí pouze ten layout. PHP kód mám stejný jako je zde na konci a v podstránce pro jistotu pouze zkopírovaný kontaktní formulář odsud...Nevíte, co s tím prosím?

 
Odpovědět 26. listopadu 10:35
Avatar
Tomáš Pour
Člen
Avatar
Tomáš Pour:26. listopadu 10:48

Jak tak zkoumám, tak si myslím, že se mi pouze změní v adrese text a nic se nestane...
index.php:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<header>
<div id="logo"></div>
<nav>
<ul>
<li>Domů</li>
<li>Kontakt</li>
<li>O mně</li>
<li>Galerie</li>
</ul>
</nav>
</header>
<article>

<section>
<?php
if (isset($_GET['s­tranka']))
$stranka = $_GET['stranka'];
else
$stranka = 'index';
if (preg_match('/^[a-z0-9]+$/', $stranka))
{
$vlozeno = include('podstran­ky/' . $stranka . '.php');
if (!$vlozeno)
echo('Podstránka nenalezena');
}
else
echo('Neplatný parametr.');
?>
</section>
</article>
<footer>
Vytvořil ©Tomáš Pour dle návodu na IT Network.
</footer>
</body>
</html>

 
Odpovědět 26. listopadu 10:48
Avatar
Tomáš Pour
Člen
Avatar
Tomáš Pour:26. listopadu 19:14

Už je to ok, blbne mi localhost a po nahrání na webhosting už funguje :-)

 
Odpovědět 26. listopadu 19:14
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 109. Zobrazit vše