Da bi se olakšao deploy aplikacija napisanih u Zend Framework-u dodajemo dvije postavke u apache-ovu vhost datoteku:
<VirtualHost *:80> ServerName test.mysite.com ServerAdmin webmaster@test.mysite.com SetEnv APPLICATION_ENV testing php_value include_path ".:/web/zf/1.10/library:/usr/share/php" DocumentRoot /web/apps/mysite.com/public <Directory /> Options All </Directory> <Directory /web/apps/mysite.com/public/> AllowOverride All </Directory> ErrorLog /web/logs/012-test.mysite.com-error.log # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. LogLevel debug CustomLog /web/logs/012-test.mysite.com-access.log combined </VirtualHost>
Već nekoliko dana pokušavam natjerati Drupalov Twitter modul da radi (ako se ovo pojavilo na twitter-u znači da mi je napokon uspjelo), ali bez ikakvog rezultata. Na mojoj lokalnoj verziji sajta je proradilo od prve, bez ikakvih problema. Na serveru jednostavno ne radi. Nikako.
Nakon nekoliko dana očajničkih pokušaja, čitanja raznih članaka (za koje se redovito pokazalo da nemaju veze s onim što je moj problem), kojekakvih brisanja cache-a (čak i direktnim izvršavanjem upita na bazi), provjeravanja dozvola datoteka modula i sl. konačno sam uspio pronaći uzrok problema. Naravno, bio je banalno jednostavan - datoteke twitter modula sam uploadao u direktorij starog bloga na habek.net (koji više ne radi) umjesto na potrebno mjesto na novom blogu na sinisa.habek.net.
Vjerojatno postoji neko pravilo koje govori da čim više vremena potrošite otkrivajući uzrok nekom problemu (iliti jednostavnije, zašto damn stvar ne radi kako bi trebala), to je taj problem jednostavniji (iliti gluplji). Ako takvo pravilo ne postoji, vjerojatno bi ga trebalo izmisliti. Blah. :-P
U prijašnjem postu sam opisao jednostavan način korištenja konfiguracije u Zend Framework aplikacijama, te sam na kraju naveo nedostatke koje ima takav pristup. U ovom postu će biti primjer konfiguracije logger-a (objekt preko kojeg se u aplikaciji logiraju događaji) kod kojeg su ti nedostaci izbjegnuti.
Ovaj put neće biti posebne konfiguracijske datoteke, a postaviti će se samo jedan konfiguracijski parametar za logiranje - log.path, tj. putanja u koju želimo da aplikacija sprema logove (stvaran primjer bi imao malo više parametara):
application/configs/application.ini:
[production] phpSettings.display_startup_errors = 0 phpSettings.display_errors = 0 bootstrap.path = APPLICATION_PATH "/Bootstrap.php" bootstrap.class = "Bootstrap" resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers" log.path = APPLICATION_PATH "/../data/log" [staging : production] [testing : production] [development : production] phpSettings.display_startup_errors = 1 phpSettings.display_errors = 1
U bootstrap-u ne spremamo konfiguraciju kao u primjeru iz prošlog posta nego te podatke koristimo za kreiranje loggera, instance Zend_Log klase koju koristimo za logiranje. Naravno, logger se sprema u registry iz kojeg ga možemo dohvatiti i koristiti iz bilo kojeg dijela aplikacije (naravno, stvarni bootstrap bi imao malo više toga):
application/Bootstrap.php:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { protected function _initAutoload() { $autoloader = Zend_Loader_Autoloader::getInstance(); $moduleLoader = new Zend_Application_Module_Autoloader(array( 'namespace' => '', 'basePath' => APPLICATION_PATH )); return $moduleLoader; } protected function _initLogger() { $options = $this->getOptions(); $logger = new Zend_Log( new Zend_Log_Writer_Stream($options['log']['path'].'/log_'.date('Y-m-d').'.log') ); Zend_Registry::set('logger', $logger); return $logger; } }
Kad trebamo nešto logirati, logger čitamo iz registry-ja i pozivamo odgovarajuću metodu na njemu:
<?php Zend_Registry::get('logger')->notice('Some application notice');
U usporedbi sa primjerom iz prijašnjeg posta:
Iako ovo baš nije najbolji način rada sa konfiguracijom može se upotrijebiti u jednostavnijim aplikacijama (u kojima ionako nema smisla previše komplicirati) ili kao brzi fix u nekoj većoj aplikaciji (s tim da bi u tom slučaju ipak to kasnije trebalo riješiti na neki kvalitetniji način).
Sami podaci se spreme u posebnu konfiguracijsku datoteku (u teoriji mogao bi se koristiti i application.ini), ali ako radite nešto takvoga sigurno se radi o parametrima koji se na neki način razlikuju i bolje ih je ne miješati sa ostalom konfiguracijom aplikacije. Npr. mogu se spremiti u options.ini datoteku:
application/configs/options.ini:
[production] image.thumbnail.width = 80 image.thumbnail.height = 80 image.preview.width = 350 image.preview.height = 350 [staging : production] [testing : production] [development : production]
Konfiguracija se čita za vrijeme bootstrap-a aplikacije i sprema u registry:
application/Bootstrap.php:
<?php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initOptions()
{
$options = new Zend_Config_Ini(APPLICATION_PATH.'/configs/options.ini', APPLICATION_ENV);
Zend_Registry::set('options', $options);
}
}
I na kraju, konfiguraciju koja je za vrijeme bootstrap-a spremljena u registry može se dobiti i koristiti kad god je to potrebno i iz bilo kojeg dijela aplikacije:
<?php $thumbWidth = Zend_Registry::get('options')->image->thumbnail->width;
Loše strane ovakvog rješenja (zato i je upotrebljivo samo za jednostavnije slučajeve i fix-eve) su: