Front-end Front-end
Probíhá výprodej HTML, JavaScript a Bootstrap. Slevy až 80 %
Vyšlehej si extra vědomosti! Až 100% bodů na prémiový obsah zdarma! Více zde

Lekce 2 - .htaccess, autoloader a obecný kontroler

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, Popis MVC architektury, jsme si vysvětlili MVC architekturu. Již víme, že stránka se bude skládat z komponent 3 typů: kontrolerů, modelů a pohledů. Dnes si připravíme prostředí, začneme souborem .htaccess, dále si v index.php nastavíme PHP dle našich potřeb a vytvoříme předka pro naše kontrolery.

Co budete potřebovat je zprovozněný lokální server (viz. XAMPP - Instalace Apache, PHP a MySQL na Windows), ale to již určitě máte. Přesuňme se tedy do výchozí složky (v XAMPP defaultně c:/xampp/htdocs) a vše v ní odstraňme.

Pozor! Je opravdu důležité, aby jste systém vložili právě do této kořenové složky, když pro něj uděláte podsložku, nebude fungovat!

Je to kvůli hezkým URL adresám, viz dále. Pokud máte na localhostu více projektů, nastavte pro projekt subdoménu.

Adresářová struktura

Vytvořme si 3 složky pro nám již známe 3 typy komponent. Budou se jmenovat: kontrolery, modely a pohledy. Rovnou si zde připravte i soubory .htaccess a index.php.

Adresářová struktura MVC frameworku v PHP

.htaccess

Určitě znáte soubor .htaccess. Slouží ke konfiguraci webserveru Apache a určuje, co se má stát, když uživatel vyťuká URL adresu. Vše se děje ještě předtím, než se vůbec spustí jazyk PHP jako takový.

Vytvořme tedy tento soubor (i s tou tečkou na začátku názvu) v kořenové složce. Kolega jednou pravil, že stejně jako nechce pochopit ženu, tak nechce pochopit .htaccess. Nastavení Apache je opravdu dost krkolomné a proto si s ním nelamte hlavu a berte ho jako hotovou věc.

Jako první zakážeme výpis souborů ve složce na webu, budou tedy zvenku skryty, což my chceme. Přidáme řádek:

Options -Indexes

Hezké URL adresy

Klasická adresa PHP aplikace vypadá asi takto:

http://wwww.domena.cz/index.php?clanek=nazev-clanku&parametr=hodnota

To je poměrně ošklivé, že? V naší aplikaci budeme používat tzv. hezké URL adresy, ta samá adresa bude u nás vypadat takto:

http://wwww.domena.cz/nazev-clanku/hodnota

To je mnohem hezčí. Zpracování URL adres necháme plně na PHP a v Apache toto "vypneme" a všechny dotazy přesměrujeme na soubor index.php, kde si URL sami zpracujeme. Apache by totiž jinak bral nazev-clanku jako složku a tam hledal podsložku hodnota a v ní index. Zapneme přesměrovávací engine a přidáme pravidlo k přesměrování, kde až na určité typy souborů v URL přesměrujeme vždy na index.php:

RewriteEngine On
# RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !\.(css|js|icon|zip|rar|png|jpg|gif|pdf)$ index.php [L]

Znak "#" je komentář, příkaz "RewriteBase /" je tedy zakomentovaný. To proto, že na localu ho nepotřebujeme, ale některé webservery v produkci (až budeme web nahrávat na internet) bez tohoto přepínače nefungují, až budete hotový web nahrávat na server, musíte to zkusit :)

RewriteCond určují, že se nemá přesměrovat v případě, že soubor nebo složka existuje. Pokud tedy voláme např.:

http://wwww.domena.cz/soubor.txt

Bude tento soubor stažen (pokud existuje) a pokud ne, budeme přesměrováni na index. Kdybychom přesměrovali úplně vše (bez těch několika podmínek), nemohli bychom stahovat žádné soubory a vždy by se nám zobrazil index. Přesměrování jsme si ještě pojistili výčtem nejdůležitějších přípon, které se nebudou přesměrovávat. Všechny ostatní URL adresy směřují na index.

Jako poslední do .htaccess přidáme zpracování přípony .phtml, aby nám nikdo nekoukal do zdrojáků šablon. Soubor .phtml se bude chovat úplně stejně, jako soubor .php. Přidejme tento řádek:

AddType application/x-httpd-php .php .phtml

Zde máme hotovo.

index.php

Vytvořme si index.php, tedy soubor, ve kterém započne veškerá komunikace a kam se budou směřovat všechny URL adresy.

Celý web budeme tvořit v kódování UTF-8, nastavte si tedy toto kódování jako výchozí ve svém editoru. Pokud používáte IDE (PHPStorm, Netbeans, Eclipse), tak tam je již velmi pravděpodobně nastavené. Pokud se vás bude editor ptát na BOM, tak s ním pracovat nebudeme (kódování UTF-8 without BOM).

Jako první samozřejmě vložíme direktivu <?php a nastavíme PHP interní kódování na UTF8, díky tomu poté budou správně fungovat PHP funkce pro práci s textovými řetězci. Docílíme toho takto:

<?php
mb_internal_encoding("UTF-8");

Autoloader

V systému budeme často tvořit instance různých tříd a je velmi nepohodlné tyto třídy ručně requirovat/in­cludovat. Proto PHP disponuje možností vytvořit funkci, která se zavolá poté, co je volána neexistující třída. V této funkci si třídu načteme. Třídy se tedy automaticky načítají ve chvíli, kdy je potřebujeme použít.

Načítat budeme vlastně 2 typy tříd: modely (ze složky modely) a kontrolery (ze složky kontrolery). Pohledy u nás nebudou třídami a budou připomínat spíše HTML stránky. Naše autoload funkce tedy bude muset poznat, zda se jedná o model nebo o kontroler a podle toho sáhne do příslušné složky. Jak to uděláme?

Opět úplně jednoduše, názvy tříd kontrolerů budou končit na Kontroler. Funkce autoload by mohla vypadat takto:

function autoloadFunkce($trida)
{
        // Končí název třídy řetězcem "Kontroler" ?
        if (preg_match('/Kontroler$/', $trida))
                require("kontrolery/" . $trida . ".php");
        else
                require("modely/" . $trida . ".php");
}

Prvotní podmínka používá tzv. regulární výraz, který ověří, zda název třídy končí řetězcem "Kontroler". Pokud ano, načte soubor ze složky kontrolery, v opačném případě třídu bude hledat ve složce modely.

Naší funkci ještě zaregistrujeme, aby ji PHP vykonávalo jako autoloader:

spl_autoload_register("autoloadFunkce");

Až budeme mít nějaké kontrolery a modely, bude nám stačit napsat:

$mu = new ManazerUzivatelu();
$smerovac = new SmerovacKontroler();

Jelikož PHP nebude vědět o třídách ManazerUzivate­lu.php ve složce modely a třídě SmerovacKontro­ler.php ve složce kontrolery, zavolá naší funkci autoload. Ta nám v prvním případě vykoná příkaz:

require('modely/ManazerUzivatelu.php');

a v druhém případě:

require('kontrolery/SmerovacKontroler.php');

Stačí založit třídu a nemusíme se o nic starat.

Třída se samozřejmě musí jmenovat stejně, jako soubor, ve kterém je obsažena, ale tak by tomu mělo být vždy.

Pozn. ve velmi starém PHP, které bohužel ještě běží na některých free serverech, není možné používat funkci spl_autoload_re­gister() a je místo ní třeba použít starší __autoload(), viz PHP manuál.

Obecný kontroler

Vytvořme si ještě abstraktní třídu pro obecný kontroler, ze kterého budou všechny naše kontrolery dědit. Ve složce kontrolery si založíme Kontroler.php. Na začátek souboru nezapomeneme vložit direktivu <?php.

Třída bude obsahovat 3 atributy. První bude pole s daty, tam si bude kontroler ukládat data získaná od modelů. Toto pole se následně předá pohledu, který data vypíše uživateli. Tímto způsobem tedy zrealizujeme předávání dat mezi modelem a pohledem. Druhý atribut bude název pohledu, který se má vypsat. Poslední atribut bude hlavička HTML stránky, přesněji 3 její atributy: titulek, keywords a description, kterou musí mít každá HTML stránka. Atributům přiřadíme i výchozí hodnoty.

<?php
abstract class Kontroler
{

        protected $data = array();
        protected $pohled = "";
        protected $hlavicka = array('titulek' => '', 'klicova_slova' => '', 'popis' => '');

}

Třída bude mít další 3 metody. Jedna bude ta hlavní, ve které zpracuje kontroler své parametry. Tu si bude každý kontroler implementovat sám, proto ji zde označíme pouze jako abstraktní. Pojmenujeme ji jednoduše zpracuj a její argument pojmenujeme $parametry:

abstract function zpracuj($parametry);

Další funkce vypíše pohled uživateli. Pokud je nějaký pohled zadaný, jednoduše ho requirujeme. Předtím rozbalíme proměnné z pole $data pomocí funkce extract. Všechny indexy (klíče) pole budou v šabloně přístupné jako běžné proměnné.

public function vypisPohled()
{
        if ($this->pohled)
        {
                extract($this->data);
                require("pohledy/" . $this->pohled . ".phtml");
        }
}

Pokud si tedy v kontroleru uložíme takto nějaký klíč do pole:

$this->data['promenna'] = 'hodnota';

V šabloně bude proměnná přistupná jednoduše takto:

<strong>Proměnná je: </strong><?= $promenna ?>

Pokud jste si všimli, že nejsou ošetřené HTML entity, máte bod. Časem to napravíme.

Jako poslední metodu si do kontroleru přidáme jednoduché přesměrování na jinou stránku a zastavení zpracování současného skriptu. Bude se nám často hodit.

public function presmeruj($url)
{
        header("Location: /$url");
        header("Connection: close");
        exit;
}

V příští lekci, Směrovač (router), si vytvoříme svůj první kontroler, bude jím směrovač (router) :) Zdrojové kódy dnešního výtvoru máte samozřejmě u článku jako vždy.


 

Stáhnout

Staženo 3233x (2.88 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?
31 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.
Předchozí článek
Popis MVC architektury
Všechny články v sekci
Jednoduchý redakční systém v PHP objektově (MVC)
Miniatura
Následující článek
Směrovač (router)
Aktivity (6)

 

 

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

Avatar
michal.smatlak:18.3.2017 15:01

Tento postup ktorý si napísal funguje až keď máš vytvorený nejaký projekt, nie? Ale ja potrebujem vytvoriť súbor mimo projektu. Jednoducho potrebujem súbor ktorý bude v koreňovej zložke htdocs a nie v podzložke projektu.

 
Odpovědět 18.3.2017 15:01
Avatar
IT Man
Redaktor
Avatar
Odpovídá na michal.smatlak
IT Man:18.3.2017 21:05

Tak to neuděláš v Netbeans, ale normálně ve Windows průzkumníku. Necháš si zobrazit přípony souborů, vytvoříš nový textový soubor a pojmenuješ ho index.php.

Odpovědět  +1 18.3.2017 21:05
Cokoliv a kdokoliv může jednou uspět.
Avatar
Petr Langer
Člen
Avatar
Petr Langer:20.8.2017 17:50

Když si v kořenovém adresáři vytvořím složku scripts a v ní budu mít nějaký script, který pak budu v hlavičce html stránky načítat (...src="../scrip­ts/script.js"). Jak udělat aby to server bral jako složku a nepřesměrovával požadavek na kontroler?

 
Odpovědět 20.8.2017 17:50
Avatar
Mr.Suit
Člen
Avatar
Mr.Suit:6.1.2018 18:40

Mozna by stalo za zminku uvest zde composer jako mozny zpusob autoloadingu.

  • doporucil bych na praci a vyvoj obecne naucit se s linuxem a zvolit nejakou vhodnou distribuci napr debian. Zde se da nasledovne virtualizovat windows pro vase oblibene programy typu photoshop, visual basic a pod vse co je psane pro win.
  • Jinak dobry clanek. Zrovna ctu a libi ... :) .
  • Jen jedna otazka: prakticky ta adresarova struktura takto asi vypadat nebude, tak jak konci dilem 9. dal jsem se nedival, zatim jsem nekoupil premiove clanky, ale myslim si, ze by bylo dobre vedet kam prijdou pohledy jakozto asi do public_html? nebo alespon ty styly.

Rad bych to pochopil v praktickem hledisku, jak je to best practice.

Diky Karel.

Odpovědět 6.1.2018 18:40
/Best Practice/Work/Life/brain.conf
Avatar
Vaclav Hrouda:26.3.2018 22:18

Zdravím, když zadám adresu example.com/pohledy (nebo název nějaké jiné složky) vyhodí to error 403. Nevíte jak tomu zabránit a zajistit aby se spustil teoretický PohledyKontro­ler.php

 
Odpovědět 26.3.2018 22:18
Avatar
ludek.balvin
Člen
Avatar
ludek.balvin:28. února 18:17

Ahoj,
jak postupovat při produkci na subdoménu? Např. pojektA.domena.cz? Na localu dle tohoto článku vše OK, ale na produkci to funguje jen v kořenové složce... Ať googlim jak googlim, tak nic nemohu najít :-(

Jinka luxusní tutoriál - díky moc!!!!

Luděk

 
Odpovědět 28. února 18:17
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na ludek.balvin
David Čápka:28. února 18:24

Subdoména by na to neměla mít vliv, to je to samé jako když napíšeš www, jde o složku. Možná máš nějak divně nastavený hosting.

Odpovědět 28. února 18:24
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
Odpovídá na ludek.balvin
Michal Šmahel:28. února 18:59

Ahoj, když nahraješ na subdoménu statickou HTML stránku, funguje nebo ne?

Odpovědět 28. února 18:59
Nejdůležitější je motivace, ovšem musí být doprovázena činy.
Avatar
ludek.balvin
Člen
Avatar
ludek.balvin:1. března 1:32

Právě, že funguje vše. Tedy vše krom této architektury MVC. :-(

 
Odpovědět 1. března 1:32
Avatar
ludek.balvin
Člen
Avatar
Odpovídá na Michal Šmahel
ludek.balvin:1. března 10:24

Davide,
prosím, jak bych měl správně popsat problém na podpoře svého hostingu? Pro info je to EBOLA.cz.
díky moc

 
Odpovědět 1. března 10:24
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 104. Zobrazit vše