Programový kód zpřehledníme rozdělením do více souborů. V případě OOP se nabízí ukládání každé třídy/interface (resp. několika úzce souvisejících tříd) do samostatného souboru. Tyto soubory je vhodné pojmenovávat podle nějaké své konvence. Následně je vkládáme do skriptů konstrukcí require_once. Opět, kvůli přehlednosti, bývá zvykem všechna vkládání umísťovat na začátky skriptů.

Odbočka: pokud použijete relativní cestu k souboru, require_once jej dohledá možná trošku nečekaným způsobem. Na include_path se také nerad spoléhám, proto se kloním k používání absolutních cest tímto způsobem:

require_once dirname(__FILE__).'/soubor.php';

Slabá místa

Tohle všechno sice přispívá ke zpřehlednění kódu, ale má to i slabé stránky:

  • vkládáme soubory, které třeba nebudeme potřebovat
  • ke každé třídě si musíme pamatovat název souboru

Obzvláště ta dualita třída ↔ soubor mi hodně vadí. Hledal jsem tedy nějaké flexibilní řešení, které by jednak odstranilo obě slabá místa, zároveň co nejvíce zjednodušilo programátorovi život a hlavně nekladlo nová omezení či pravidla.

Řešení

Řešením je Nette\Loaders\RobotLoader. Základem je magická funkce __autoload. Díky ní se soubor s definicí třídy vloží až ve chvíli, kdy je skutečně potřeba.

Nette má vlastní obsluhu __autoload(). Jejím jádrem je vcelku jednoduchá funkce, která v adresáři webové aplikace proběhne všechny PHP skripty (tedy i podadresářích) a pomocí funkce token_get_all v nich vyhledá definice tříd a rozhraní. Výsledkem je tabulka identifikátorů a relativních cest k souborům. Nette pak přesně ví, který soubor při požadavku na konkrétní třidu vložit. Je to velice rychlé. Tabulka se samozřejmě uchovává v cache.

Při nahrání nové verze aplikace na web lze jedním příkazem tabulku vygenerovat znovu, nebo ještě jednodušeji – stačí smazat příslušný soubor a vygeneruje se sama.

aktualizace: Nette může běžet v tzv. vývojářském režimu (DEVELOPMENT). Pokud v tomto režimu není třída nalezena, provede se automaticky regenerace cache. Nepomůže-li to, ohlásí se error.

Výhody řešení

  • zbavíte se všech volání require_once
  • vkládají se jen potřebné soubory
  • bez striktních konvencí pojmenování souborů
  • možno mít více tříd v jednom souboru
  • není třeba ručně udržovat tabulku
  • Nette již při generování odhalí konflikty názvů
  • připadáte si jako v kompilovaném jazyce

Je to prostě velmi pohodlné a krutě návykové 🙂