Určitě to znáte, při programování PHP scriptů si rozdělíme kód na mnoho souborů a abychom měli k dispozici všechny části, tak je načteme sérií volání `include`, `require` nebo nejlépe `require_once`, což zaručí načtení právě jednou.
V kódu to pak vypadá třeba takto:
require_once 'Router.php';require_once 'Page.php';require_once 'Paginator.php';
Hlavní nevýhoda tohoto přístupu je v tom, že programátor musí neustále hlídat, aby měl vždy všechno načteno. Pokud toho ale načte hodně, tak přichází zbytečně o výkon a mnohokrát se sahá na disk. Ruční řešení má tedy jen samé problémy.
Naštěstí v PHP existuje nativní podpora pro tzv. Autoloading tříd, což je logika v kódu, která načte soubor s třídou až v okamžiku, kdy je poprvé potřeba (typicky při prvním vytváření instance).
Jednoduchá implementace pak může vypadat třeba takto:
spl_autoload_register(function (string $className): void {include 'src/' . $className . '.php';});$obj = new MyClass1();$obj2 = new MyClass2();
Funkce spl_autoload_register
při vytváření instance třídy MyClass1
načte soubor MyClass1.php
z adresáře src
. Tato implementace předpokládá, že je každá třída v samostatném souboru, který se jmenuje názvem třídy nebo rozhraní.
V reálné aplikaci může nastat mnoho nepříjemných situací, které komplikují autoload, a to například:
Pro toto všechno však nemusíme programovat vlastní řešení, ale můžeme použít již jednou navržené a existující.
Pokud používáte Composer, tak pravděpodobně používáte i jeho nativní autoloading. Při instalaci jakéhokoli balíku totiž Composer automaticky generuje tzv. class map
, což je přehled tříd a jejich fyzické umístění.
Na začátku kódu (typicky v index.php
) pak stačí použít:
require __DIR__ . '/vendor/autoload.php';
Autoloading se však vygeneruje jen jednou při zavolání příkazu composer dump
, proto je potřeba při každé změně aplikace autoloding přegenerovat.
Pro lokální vývoj se mi velmi líbí balík nette/robot-loader
, který automaticky prochází adresářovou strukturu a umístění tříd si ukládá do cache. Pokud tedy načítáme třídu, nejprve se podívá do cache a až pokud neexistuje, tak provede automatické přeindexování projektu. Programátor proto nemusí vůbec hlídat, kde je jaký soubor nebo třída umístěna a prostě programuje.
Instalace přes Composer:
composer require nette/robot-loader
Základní vysvětlení funkčnosti popisuje sama dokumentace:
Podobně, jako Google robot prochází a indexuje webové stránky, tak i RobotLoader prochází všechny PHP skripty a zaznamenává si, které třídy, rozhraní a traity v nich našel. Výsledky bádání si poté uloží do cache a použije při dalším požadavku. Stačí tedy určit, které adresáře má procházet a kam ukládat cache.
Použití je pak extrémně snadné:
$loader = new Nette\Loaders\RobotLoader;// přidáme adresáře, které má RobotLoader indexovat$loader->addDirectory(__DIR__ . '/app');$loader->addDirectory(__DIR__ . '/libs');// nastavíme cachování na disk do adresáře 'temp'$loader->setTempDirectory(__DIR__ . '/temp');$loader->register(); // spustíme RobotLoader
Nastavením $loader->setAutoRefresh(true nebo false)
určíme, zda má RobotLoader reindexovat soubory, když narazí na novou třídu. To by mělo být vypnuto na produkčních serverech.
Tak, a od teď už nemusíte autoloading nikdy řešit.
Při vývoji reálného projektu používám kombinované řešení.
Reálně to funguje tak, že nainstalované balíky načítám přes Composer autoload (který je velmi efektivní) a tím se vyřeší loading všech tříd v adresáři vendor
.
Kód konkrétního projektu je pak umístěn v adresáři app
, kde řeším autoloading jen několika málo tříd přes RobotLoader. Důležité je, aby byla konkrétní aplikace vždy co nejmenší a maximálně se používaly hotové balíky, hodně to podporuje znovupoužitelnost.
Struktura projektu pak vypadá třeba takto:
/app
Bootstrap.php <-- konfigurace
/model
UserForm.php <-- projektové třídy
RegisterFactory.php
...
/vendor
... <-- knihovny
/www
index.php <-- inicializace
Někdy se může stát, že se ne vždy každý soubor načte a budete zjišťovat potíže.
Pro debugování doporučuji funkci get_included_files().
Jan Barášek Více o autorovi
Autor článku pracuje jako seniorní vývojář a software architekt v Praze. Navrhuje a spravuje velké webové aplikace, které znáte a používáte. Od roku 2009 nabral bohaté zkušenosti, které tímto webem předává dál.
Rád vám pomůžu:
Nabízím trénink vývojářů, konzultace, školení a analýzu návrhových vzorů. Osobně v Praze nebo online.
Napište mi, pokud si nevíte rady.
Lektor: Jan Barášek
Články píše Jan Barášek © 2009-2024 | Kontakt | Mapa webu
Status | Aktualizováno: ... | cs