Internet Info, s.r.o. Lupa Měšec Podnikatel Root Zdroják DigiZone Slunečnice Vitalia TopDrive KupDnes Navrcholu NovýTarif Dobrý web Weblogy Woko Jagg Computer.cz SK: MojeLinky

Hlavní navigace

Nette Framework: adresářová struktura aplikace

Pokračujeme s aplikací Automat na kávu a zaměříme se na její adresářovou strukturu. K čemu slouží zaváděcí soubor a jak souvisí Nette Framework se životním prostředím? Lze dát sbohem příkazu require_once?

Tweetni to Twitter Jaggni to! Jagg Del.icio.us Delicious

Pojďme se podívat podrobněji na adresářovou strukturu a jednotlivé soubory aplikace Automat na kávu (ke stažení na konci článku). Celý projekt je rozdělen do tří adresářů:

  • app  – obsahuje všechny soubory serverové části aplikace
  • libs  – obsahuje knihovny třetích stran, mohou být společné pro více aplikací
  • document_root  – kořenový adresář dostupný přes prohlížeč

Jakýkoliv požadavek na HTTP server je směrován dovnitř adresáře document_root. Zde se nacházejí všechny obrázky, kaskádové styly, javascriptové soubory. A také soubor index.php, přes který vedou všechny požadavky na HTML stránky. Pokud bychom používali tzv. Cool URL, vytvořili bychom pravidlo mod_rewrite, které by opět všechny požadavky na stránku nasměrovalo skrz index.php.

Přičemž index.php nedelá nic jiného, než že definuje cesty k ostatním dvou adresářům app a libs (jako konstanty) a předá řízení zaváděcímu souboru aplikace.

define('WWW_DIR', dirname(__FILE__)); // path to the web root
define('APP_DIR', WWW_DIR . '/../app'); // path to the application root
define('LIBS_DIR', WWW_DIR . '/../libs'); // path to the libraries

require APP_DIR . '/bootstrap.php'; // load bootstrap file 

Pojmenování a umístění jednotlivých adresářů je zcela ve vaší režii. Pokud preferujete jiné konvence, račte si je dopřát. Stačí jen změnit cesty v  index.php a aplikace dál poběží, jako by se nechumelilo. Nezapomeňte dohlédnout na to, aby adresáře aplikace a knihoven byly nepřístupné z webového prohlížeče. Například pomocí pravidel v souboru  .htaccess:

Order Allow,Deny
Deny from all 

Zaváděcí soubor

Zaváděcí soubor app/bootstrap.php nejprve vykoná nám již známé operace. Načte framework, aktivuje Laděnku a pro jistotu zkontroluje, zda lze zapisovat do adresáře pro dočasné soubory.

// Krok 1: Načtení Nette Framework
require LIBS_DIR . '/Nette/loader.php';

// Krok 2: Konfigurace prostředí
// 2a) zapne Nette\Debug pro lepší vizualizaci a zpracování chyb
Debug::enable();

// 2b) kontrola, zda je složka /app/temp zapisovatelná
if (@file_put_contents(Environment::expand('%tempDir%/_check'), '') === FALSE) {
        throw new Exception("Make directory '" . Environment::getVariable('tempDir') . "' writable!");
} 

Poté následuje nastavení routeru a samotné spuštění aplikace. Zatímco routování je kapitolou samo o sobě (tedy alespoň z pohledu tohoto seriálu), o třídě Nette\Environ­ment, jejíž jméno v ukázce zdrojového kódu padlo, si něco povíme hned.

Třída Environment

Kladnozelený vztah Nette Frameworku k životnímu prostředí webové aplikace signalizuje skutečnost, že si nevytváří žádné globální proměnné nebo konstanty. Celé prostředí má pod palcem statická třída Nette\Environ­ment. Ta slouží jako globální úložiště pro:

  • proměnné prostředí (obvykle cesty, třeba k dočasnému adresáři)
  • název a režimy prostředí
  • konfiguraci aplikace
  • singletony

Proměnné prostředí lze nastavit a získat pomocí těchto dvou metod:

// pokud používáte verzi pro PHP 5.3, odkomentujte následující řádek:
// use Nette\Environment;

Environment::setVariable('foo', 'Hello World');
echo Environment::getVariable('foo'); // -> Hello World 

Framework zjednoduší provázání i na konstanty definované v souboru index.php. Pokud například požádáte o nedefinovanou proměnnou appDir, zkusí se podívat, jestli neexistuje konstanta APP_DIR a vrátit její hodnotu. Hlavní výhoda tohoto řešení se projeví při využití další vlastnosti konstant, a tou je rozvíjení.

// mezi znaky % je název konstanty
Environment::setVariable('foo', 'Rozvíjej se %poupatko%');
Environment::setVariable('poupatko', 'programátore');
echo Environment::getVariable('foo'); // -> Rozvíjej se programátore 

Díky tomu je možné definovat jako proměnné absolutní cesty, ačkoliv známe jen cestu relativní. Například jako dočasný adresář chceme nastavit app/temp, ale absolutní cestu k app  neznáme (tu definuje index.php konstatnou APP_DIR). Lze však nastavit:

Environment::setVariable('tempDir', '%appDir%/temp');
echo Environment::getVariable('tempDir');
// -> vypíše absolutní cestu, neboť nahradí %appDir% za konstantu APP_DIR 

Pro rozvinutí proměnné bez její definice lze použít metodu expand, jak toho využívá kód v  bootstrap.php ověřující, zda lze do dočasného adresáře zapisovat.

Sbohem všem require dej

PHP disponuje čtyřmi příkazy pro načtení skriptu z jiného souboru. Tedy require, include a jejich sourozenci s koncovkou _once. Pokud je cesta k souboru relativní, dohledává se skript mně naprosto nepochopitelným způsobem, proto také poučení programátoři používají cesty absolutní. A jelikož magická konstanta __DIR__ přijde až s PHP 5.3, hromadí se na začátcích souborů haldy něčeho takového:

require_once dirname(__FILE__) . '/libs/ClassA.php';
require_once dirname(__FILE__) . '/libs/ClassB.php';
require_once dirname(__FILE__) . '/libs/ClassC.php';
... 

Z estetického hlediska jde o zástupce ASCII art deco, povšimněte si zvláště půvabného spojení závorek s podtržítky. V odborných kruzích však podobné obrazy nesou název „Serverova smrt“ a společně s výjevem Hieronyma Bosche „.htaccess obsahující 486 pravidel RewriteRule“ se jimi straší malé, čerstvě vylíhlé, revize Apache.

Skutečně se ukazuje, že jedním z největších zabijáků výkonu PHP je načítání velkého množství souborů (navíc nejsou-li absolutně adresováné). Co se s tím dá dělat? Účinnou zbraní je kompaktní minimalizovaná verze frameworku, viz první díl seriálu. Díky ní celý Nette Framework načtete jedním jediným příkazem:

require 'Nette/loader.php'; 

Pokud ale minimalizované verze nejsou k dispozici nebo by jejich použití nebylo vhodné, dá se dosáhnout velké úspory výkonu tím, že budeme načítat pouze soubory, které skutečně potřebujeme. A tomu slouží autoloading.

Nutno říci, že zvýšení výkonu aplikací je pouze druhotným efektem autoloadingu. Prim drží pohodlí, které s ním programátor získá. Bude moci přestat používat příkaz require a velmi rychle zjístí, jak je to návykové.

Autoloading zajišťuje obslužná funkce, která jako parametr dostane jméno třídy/interface a jejím úkolem je načíst skript s definicí. Otázkou zůstává, jak obecně odvodit z názvu třídy jméno souboru?

(Poznámka: špatně napsaný autoloadovací handler může vést k citelnému snížení výkonu aplikace.)

(Poznámka č.2: vyšší zátěž serverů vede ke globálnímu oteplování serverovny.)

RobotLoader

Třída Nette\Loaders\RobotLoader na to jde způsobem, který znáte od vyhledávačů. Podobně jako roboti vyhledávačů procházejí a indexují všechny stránky, tak i RobotLoader prochází všechny PHP skripty a zaznamenává si, které třídy a rozhraní v nich našel. Výsledky bádání si poté uloží do cache a použije při dalším HTTP požadavku. Stačí tedy určit, které adresáře má procházet (předpokládejme, že cesty se nacházejí v konstantách APP_DIRLIBS_DIR):

Následující řádky je možné přidat do zaváděcího souboru bootstrap.php a poté lze odstranit všechny require_once použité v aplikaci.

// pokud používáte verzi pro PHP 5.3, odkomentujte následující řádek:
// use Nette\Loaders\RobotLoader;

$loader = new RobotLoader();
$loader->addDirectory(APP_DIR);
$loader->addDirectory(LIBS_DIR);
$loader->register(); 

Pokud byste chtěli využít služeb RobotLoaderu mimo MVP aplikace Nette, je potřeba nastavit cestu k dočasnému adresáři do proměnné prostředí  tempDir:

Environment::setVariable('tempDir', '/absolutní/cesta/k/temp'); 

RobotLoader pracuje s cache inteligentně. Při vytvoření nové třídy ji invaliduje a zároveň si pamatuje, které třídy v adresářové struktuře nenašel. Můžete tedy pohodlně rozvíjet svou aplikaci a RobotLoader vám v tom bude sekundovat.

Ještě perlička na závěr: pokud byste chtěli určitý podadresář z indexování vynechat, vytvořte soubor netterobots.txt se známou syntaxí:

Disallow: Zend 
Zdrojový kód ukázek je k dispozici ke stažení.

Pokračování příště

Příště nás čeká atraktivní téma: JavaScript, AJAX a bohaté aplikace.


Autor článku je vývojář na volné noze, specializuje se na návrh a programování moderních webových aplikací. Pravidelně pořádá školení pro tvůrce webových aplikací, vyvíjí open-source knihovny Texy, dibi a Nette Framework.

David Grudl

David Grudl

David Grudl je autorem PHP knihoven Nette Framework, databázové vrstvy dibi a formátovače HTML kódu Texy!.

Školení Google+ pro firmy

DW - Školení PPC
  • Jak využít Google+ pro firemní komunikaci a marketing.
  • Čím se liší Google+ od Twitteru a Facebooku z pohledu firemního využití.
  • Jak využít Google+ v souladu s pravidly užívání.
  • Založení Google+ Page (Stránky) krok po kroku, včetně praktických tipů.

Detailní informace o školení Google+ »

Přehled názorů

Styl Wordpressu
Mastodont 14. 4. 2009 10:09
Nový
├ 
Re: Styl Wordpressu
Martin Malý 14. 4. 2009 11:46
Nový
│
└ 
Re: Styl Wordpressu
Mastodont 14. 4. 2009 13:56
Nový
│
 
└ 
Re: Styl Wordpressu
Martin Malý 14. 4. 2009 13:59
Nový
├ 
Re: Styl Wordpressu
Jiří Knesl 14. 4. 2009 12:21
Nový
└ 
Re: Styl Wordpressu
David Grudl 14. 4. 2009 14:24
Nový
Autoloader
Martin Malý 14. 4. 2009 11:51
Nový
├ 
Re: Autoloader
aprilchild 14. 4. 2009 12:10
Nový
│
└ 
Re: Autoloader
Martin Malý 14. 4. 2009 12:16
Nový
└ 
Re: Autoloader
David Grudl 14. 4. 2009 12:24
Nový
 
└ 
Re: Autoloader
Martin Malý 14. 4. 2009 12:41
Nový
 
 
├ 
Re: Autoloader
David Grudl 14. 4. 2009 12:53
Nový
 
 
│
└ 
Re: Autoloader
Martin Malý 14. 4. 2009 12:59
Nový
 
 
└ 
Problém vrstvy navíc
v6ak 14. 4. 2009 14:29
Nový
 
 
 
└ 
Re: Problém vrstvy navíc
Martin Malý 14. 4. 2009 15:08
Nový
 
 
 
 
├ 
Re: Problém vrstvy navíc
v6ak 14. 4. 2009 15:22
Nový
 
 
 
 
│
└ 
Re: Problém vrstvy navíc
Martin Malý 14. 4. 2009 15:27
Nový
 
 
 
 
└ 
Re: Problém vrstvy navíc
Jiří Knesl 14. 4. 2009 16:15
Nový
 
 
 
 
 
├ 
Re: Problém vrstvy navíc
Martin Malý 14. 4. 2009 17:07
Nový
 
 
 
 
 
└ 
Re: Problém vrstvy navíc
v6ak 14. 4. 2009 17:47
Nový
RE: Nette Framework: adresářová struktura aplikace
yeah 14. 4. 2009 14:15
Nový
Víc konfigurací
Borek Bernard 14. 4. 2009 22:33
Nový
└ 
Re: Víc konfigurací
David Grudl 14. 4. 2009 22:47
Nový
 
├ 
Re: Víc konfigurací
Borek Bernard 14. 4. 2009 22:55
Nový
 
└ 
Re: Víc konfigurací
Pavel Voska 15. 4. 2009 04:13
Nový
 
 
├ 
Re: Víc konfigurací
Tomáš Vítek 15. 4. 2009 18:13
Nový
 
 
└ 
Re: Víc konfigurací
David Grudl 15. 4. 2009 18:19
Nový
 
 
 
└ 
Re: Víc konfigurací
Srigi 16. 4. 2009 17:12
Nový
RE: Nette Framework: adresářová struktura aplikace
Miloslav Pojman 15. 4. 2009 13:59
Nový
├ 
RE: Nette Framework: adresářová struktura aplikace
David Grudl 15. 4. 2009 14:28
Nový
│
├ 
RE: Nette Framework: adresářová struktura aplikace
v6ak 15. 4. 2009 15:25
Nový
│
└ 
RE: Nette Framework: adresářová struktura aplikace
Miloslav Pojman 15. 4. 2009 17:24
Nový
│
 
└ 
RE: Nette Framework: adresářová struktura aplikace
David Grudl 15. 4. 2009 18:15
Nový
│
 
 
├ 
RE: Nette Framework: adresářová struktura aplikace
David Grudl 15. 4. 2009 18:16
Nový
│
 
 
└ 
RE: Nette Framework: adresářová struktura aplikace
Miloslav Pojman 16. 4. 2009 14:01
Nový
│
 
 
 
└ 
RE: Nette Framework: adresářová struktura aplikace
David Grudl 16. 4. 2009 16:45
Nový
└ 
RE: Nette Framework: adresářová struktura aplikace
Jakub Vrána 16. 4. 2009 14:22
Nový
 
└ 
RE: Nette Framework: adresářová struktura aplikace
Miloslav Pojman 16. 4. 2009 15:22
Nový
 
 
└ 
RE: Nette Framework: adresářová struktura aplikace
Jakub Vrána 16. 4. 2009 15:35
Nový
 
 
 
└ 
RE: Nette Framework: adresářová struktura aplikace
Miloslav Pojman 16. 4. 2009 18:02
Nový
 
 
 
 
└ 
RE: Nette Framework: adresářová struktura aplikace
Jakub Vrána 16. 4. 2009 19:07
Nový
       

Tento text je již více než dva měsíce starý. Chcete-li na něj reagovat v diskusi, pravděpodobně vám již nikdo neodpoví. Pro řešení aktuálních problémů doporučujeme využít naše diskusní fórum.

Zasílat nově přidané příspěvky e-mailem