K tomuto příspěvku mě dotlačilo toto téma na českém ZF fóru, ale především tři noci prosezené u psaní a konečné formulace bootstrap file pro projekt My Town Game, o kterém vám v blízké době povím něco více. Zakrývám si oči pravou rukou, otáčím se a ulehám do kouta. Harvejsi, měl jsem bootstrap tak veliký a nepřehledný, že jsem byl donucen ho přepsat do nekoncepční třídy s originálním názvem Application. Kromě tebou zmiňované přehlednosti má nekoncepční třída bootstrap filu ještě takovou výhodu, že se u každé metody dá napsat pěkný phpDoc komentář, který mi vždy připomene, co že se to teď vlastně louduje. Takže se ti předem omlouvám a nedivím se, proč je kolem vývoje třídy Zend_Application takové vzrůšo. Dovolil bych si tedy tvrdit, že pokud se jedná o větší ZF projekt, jehož bootstrap file by byl v základním znění nepřehledný, je výhodné, naházet to všechno do nekoncepční třídy. Musím tedy přihmouřit své OOoči…
Ehm, a co že to ta nekoncepční bootstrap třída vlastně je? Představte si, že váš bootstrap file index.php (www/index.php) bude vypadat následovně a že statická metoda s divokým názvem run() se postará o všechno, co je třeba:
|
1
2 3 4 5 |
// include class Application
require_once '..' . DIRECTORY_SEPARATOR . 'application' . DIRECTORY_SEPARATOR . 'Application.php'; // execute the application Application::run(); |
Přesuneme se dále do třídy Application (application/Application.php), která implementuje návrhový vzor singleton, protože aplikaci přece nebudeme spouštět vícekrát najednou, a to i kdyby měla Sofie S. zůstat sama samotinká. Tato metoda potom ve zkratce zavolá po sobě seřazenou většinu loudovacích metod, které jsou ve třídě dostupné. To je kalibr!
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/**
* This method execute the application * * @return void */ public static function run() { self::getInstance()->_setErrorReporting(); // error reporting level self::getInstance()->_setDefaultTimezone('Europe/Prague'); // default timezone self::getInstance()->_setApplicationDir(); // application directory self::getInstance()->_setIncludePath(); // include path self::getInstance()->_registerAutoload(); // autoloader self::getInstance()->_netteDebug(); // Nette debug self::getInstance()->_loadConfig(); // loading configuration self::getInstance()->_initCache(); // cache self::getInstance()->_doctrineConnect(); // database connection self::getInstance()->_initRouter(); // router self::getInstance()->_initFrontController(); // front controller self::getInstance()->_dispatch(); // dispatch } |
Všechny takto volané metody jsou soukromé a vykonávají část bootstrap funkcionality, která se takto dá velmi jednoduše dokumentovat pomocí phpDoc u každé této metody a samozřejmě také rozšiřovat novými metodami. Třída pak může obsahovat ještě pomocné soukromé metody nebo veřejné metody pro přístup z pluginů nebo z controllerů. Na ukázku ještě detail metody pro připojení do databáze:
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/**
* Doctrine lazy database connection * It creates a connection string by class Tools_Doctrine and it forwards this string * to Doctrine manager. * * @link http://www.doctrine-project.org/Doctrine_Manager/1_0#method_connection * @see class Doctrine_Manager * @see class Tools_Doctrine * @return void */ private function _doctrineConnect() { $connection = Tools_Doctrine::getConnectionString($this->_config->database); Doctrine_Manager::connection($connection); $connection = null; } |
No a konečně disponuje nekoncepční bootstrap třída výhodou, že si může všechno zapamatovat ve svých členských proměnných a o použití Zend_Register si můžete nechat během teplých letních nocích jen zdát. Následující kód zobrazuje příklad deklarace členských proměnných.
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
/**
* Single instance of class Application * * @staticvar Application */ private static $_instance = null; /** * Application directory * * @var string */ private $_dir = ''; /** * Configuration object * * @var Zend_Config */ private $_config = null; /** * Cache object * * @var Zend_Cache */ private $_cache = null; /** * Router * * @var Zend_Controller_Router_Rewrite */ private $_router = null; /** * Language * * @var string */ private $_language = ''; /** * Application locale * * @var Zend_Locale */ private $_locale = null; /** * Translation object * * @var Zend_Translate */ private $_translator = null; /** * Instance of Front Controller * * @var Zend_Controller_Front */ private $_frontController = null; |
Vše co je libo je prostě přístupné a tak si ještě nakonec shrneme výhody a nevýhody nekoncepční bootstrap třídy. Mezi výhody patří:
- přehlednost
- dokumentovatelnost
- rozšiřovatelnost
- přístupnost
- znovupoužitelnost
A mezi nevýhody patří:
- nekoncepčnost
- rychlost (zanedbatelná)
Stejně jako jsem v článku o kategorizaci přístupu k tvorbě PHP projektu neodsuzoval žádný z přístupů, tak ani v tomto případě netvrdím, že některý způsob tvorby bootstrap filu je obecně nejlepší. Proč si myslíte, že to Zend Framework nechává otevřené a předává tuto starost na samotné programátory?
22.3.2009 13:02