Úvod
V příspěvku se zmíním o způsobu a správě „importů“ (tzv. autoloading) php souborů v samotném PHP a poté se dozvíme, jak autoloading php souborů řeší Zend Framework.
- Autoloading v PHP
- Správa importů v PHP
- Jak "importovat" v PHP soubory
- Jak funguje mechanismus importů v PHP
- Autoloading v Zend Framework
Autoloading v PHP
Základem při psaní aplikací v PHP je nutné si uvědomit, jak funguje tzv. autoloading php souborů. V PHP neexistují importy jako je známe např. z Java. Když například potřebujete konstruhovat třídu jejíž definice je v jiném souboru – je nutné si tento soubor za pomocí konstrukce require nebo require_once(include, include_once) “naimportovat“ do svého souboru (předpokladem, je že soubory jsou umístěné na include_path). Dalším řešením je překrýt funkci autoload.
Správa importů v PHP
Správa “importů” souborů v php mi přijde neštastná. Jedná se do jisté míry o problém, alespoň pro mne – jsem vývojářem v Java, kde tento mechanismus je zajištován za pomocí Eclipse IDE, který se postará o seznam všech tříd, které v rámci souborů používám – jinak řečeno se o tuto oblast při vývoji vůbec nestarám.
Jak "importovat" v PHP soubory
Jak vlastně vývojář v PHP zajistí import souborů? Existují dvě cesty, které jsem již představil výše:
- použití nativních funkcí PHP (include, include_once,require nebo require_once),
- překrýt funkci autoload (od verse PHP 5+)
První způsob je použitelný, pakliže je aplikace jednoduchá a manuální správa importů je víceméně triviální. Import je řešen uvedením “filepath” k požadovaného souboru ve formě stringu a předání ji výše uvedeným funkcím (např. include(“cesta/k/souboru.php”)) . Druhý způsob je již elegantnějším způsobem, jak zajistit import souborů automaticky.
Jak funguje mechanismus importů v PHP
PHP se snaží soubor najít na základě filepath uvedenou v parametru funkce, v případě, že není cesta uvedena, snaží se najít soubor na základě definované include_path. Když soubor není nalezen ani na include_path, pak se jej snaží najít v tom samém adresáři, kde se naléza soubor, který tento import souboru “zavolal”. Když jej nenalézá mechanismus generuje hlášení – v případě include(_once) WARNING, v případě require(_once) generuje FATAL_ERROR – přehled popisu chyb naleznete v článku Chybová hlášení v PHP.
Autoloading v Zend Framework
Autoloading má na starosti implementace Zend_Loader. Autoloading je úzce spjatý s adresářovou strukturou projektu. Vše vychází z předpokladu – název třídy implementované v souboru je zároveň předpisem jeho “package-path”, kde jej autoloader nalezne. Nicméně umísťění souboru na include_path a následný “import” za pomocí nativních funkcí php je stále možný. ZF vás v tomto ohledu vůbec neomezuje.
Příklad ukazuje jak zapsat název třídy, která bude umístěna v :
%APACHE_HOME%/htdocs/zendapp/testdir/Person.php
class Zendapp_Testdir_Person { //nazev tridy je plna package path, //Zendapp je namespace, ale to vysvetlim pozdeji }
Je zřejmé, že název tříd hraje klíčovou roli v autoloadingu v rámci ZF projektu. Autoloading je víceměné automatická záležitost. Je potřeba nakonfigurovat prostředí – registrace modulu a namespace modulu. Dále namapování adresářů umístěné v namespace modulu. Když toto splníte – autoloading v rámci ZF projektu je k Vaším službám připravena. Existuje však způsob jak si autoloading „upravit“. ZF vývojáři jsou v tomto ohledu velmi praktičtí a nabízejí velmi obecné řešení, které je snadno překrytelné vlastní implementací.
V oficiální dokumentaci je uvedeno, že cíle a návrh autoloadingu jsou následující:
- dohledání třídy dle namespace – což je prefix, který deklaruje adresář, kde nalezne adresářovou strukturu vašeho projektu a třídy v něm uložené
- automatický autoloading (tzv. fallback autoloading), což zjednodušeně znamená, že definujeme pouze prefix namespace, ale nedeklarujete, do jakého adresáře je namapován
- je možné konfigurací „potlačit“ (supress) chyby
- překrýt ZF autoloading mechanismus svou implementací
Poznámka k bodu dva – fallback autoloading. Jedná se o to, že není nutné konfigurovat (mapovat) strukturu projektu. Pouze zaregistrujete příslušný prefix namespace, dle kterého se autoloader bude snažit dohledat vaše třídy. Jednoduché, ale ZF dokumentace hovoří jasně – není to doporučováno. Jak tedy tento způsob autoloadingu nastavit – v souboru %APACHE_HOME%/htdocs/zendapp/index.php
:
require_once 'Zend/Loader/Autoloader.php'; Zend_Loader_Autoloader::getInstance(); $loader->setFallbackAutoloader(true);
Existuje však i cesta, jak se také vyhnout konfiguraci a říct autoloaderu, že vaše třídy budou např. začínat prefixy Admin, Salary. A ať si je najde sám. Sice to není ideál, ale lepší než používat výše uvedené nastavení autoloadingu:
require_once 'Zend/Loader/Autoloader.php'; Zend_Loader_Autoloader::getInstance(); $loader->registerNamespace(array('Admin_', 'Blog_'));
Případně pro nastudování případných úskalí „bezkonfiguračního autoloadingu“ se mrkněte přímo do dokumentace.
Komentáře