25

I have a Zend Framework application based on the quick-start setup.

I've gotten the demos working and am now at the point of instantiating a new model class to do some real work. In my controller I want to pass a configuration parameter (specified in the application.ini) to my model constructor, something like this:

class My_UserController extends Zend_Controller_Action { public function indexAction() { $options = $this->getFrontController()->getParam('bootstrap')->getApplication()->getOptions(); $manager = new My_Model_Manager($options['my']); $this->view->items = $manager->getItems(); } } 

The example above does allow access to the options, but seems extremely round-about. Is there a better way to access the configuration?

7 Answers 7

48

I always add the following init-method to my bootstrap to pass the configuration into the registry.

protected function _initConfig() { $config = new Zend_Config($this->getOptions(), true); Zend_Registry::set('config', $config); return $config; } 

This will shorten your code a little bit:

class My_UserController extends Zend_Controller_Action { public function indexAction() { $manager = new My_Model_Manager(Zend_Registry::get('config')->my); $this->view->items = $manager->getItems(); } } 
Sign up to request clarification or add additional context in comments.

5 Comments

That will take a little work to re-parse the array into an object. If you prefer having the config as an array, it's just "Zend_Registry::set('config', $this->getOptions());" though you'll have to get it out into a variable before getting the value.
@Alister: You're right, the faster way would be to store the options-array inside the registry - but storing the array each time you'd like to retrieve a single value can be cumbersome.
This is no different than the $GLOBALS['application'] idea below, with the added benefit that $GLOBALS['application'] works probably 99% of the time.
On the other hand, Zend_Registry::get('config') requires the controller/module developer to coordinate with Bootstrap to get the config into registry.
Sure, a singleton is always some OOP-way of a global variable. Nevertheless the Registry pattern is a common and recognized way of distributing resources throughout an application. The use of Zend_Registry allows you to provide a custom object as its repository to extend its functionality into a service locator or dependency injection container. All those things are not possible with the GLOBALS approach. I don't see why the Zend_Registry approach should not work 100% of the time by the way.
22

Since version 1.8 you can use the below code in your Controller:

$my = $this->getInvokeArg('bootstrap')->getOption('my'); 

Comments

5

Alternatively, instead of using Zend_Registry you could also create a singleton Application class that will contain all application info, with public member functions that allow you to access the relevant data. Below you can find a snippet with relevant code (it won't run as is, just to give you an idea how it can be implemented) :

final class Application { /** * @var Zend_Config */ private $config = null; /** * @var Application */ private static $application; // snip /** * @return Zend_Config */ public function getConfig() { if (!$this->config instanceof Zend_Config) { $this->initConfig(); } return $this->config; } /** * @return Application */ public static function getInstance() { if (self::$application === null) { self::$application = new Application(); } return self::$application; } /** * Load Configuration */ private function initConfig() { $configFile = $this->appDir . '/config/application.xml'; if (!is_readable($configFile)) { throw new Application_Exception('Config file "' . $configFile . '" is not readable'); } $config = new Zend_Config_Xml($configFile, 'test'); $this->config = $config; } // snip /** * @param string $appDir */ public function init($appDir) { $this->appDir = $appDir; $this->initConfig(); // snip } public function run ($appDir) { $this->init($appDir); $front = $this->initController(); $front->dispatch(); } } 

Your bootstrap would look like this :

require 'Application.php'; try { Application::getInstance()->run(dirname(dirname(__FILE__))); } catch (Exception $e) { header("HTTP/1.x 500 Internal Server Error"); trigger_error('Application Error : '.$e->getMessage(), E_USER_ERROR); } 

When you want to access the configuration you would use the following :

$var = Application::getInstance()->getConfig()->somevar; 

Comments

3

In most ZF apps, the application object is declared in the global scope (see public/index.php in apps created with ZFW_DISTRIBUTION/bin/zf.sh).

It's not exactly the ZF way, but you can access the object with $GLOBALS['application']. It kinda feels like cheating, but if you're after performance, this will likely be the quickest option.

$manager = new My_Model_Manager($GLOBALS['application']->getOption('my')); 

3 Comments

It's always possible to circumvent the framework and all its abstractions. A solution like this should be a all-else-fails hack, not a go-to solution. Performance is unlikely to be critical in any case; a config variable need not be fetched inside a performance-critical loop.
What's the My_Model_Manager??
@zardilior my best guess (4 years on) is that it is a hypothetical user-land class that depends on a hypothetical user-defined option 'my'. Both of these are gleened from the SO question ;-)
1
$this->getInvokeArg('bootstrap')->getOptions(); // or $configDb = $this->getInvokeArg('bootstrap')->getOption('db'); 

Comments

0

I've define a short hand in some place I require_once() in the beginning of boostrap:

function reg($name, $value=null) { (null===$value) || Zend_Registry::set($name, $value); return Zend_Registry::get($name); } 

and in the bootstrap I have a:

protected function _initFinal() { reg('::app', $this->getApplication()); } 

then I can get the Application instance anywhere by use:

$app = reg('::app'); 

Comments

0

A really simple way to access the configuration options is by directly accessing the globally defined $application variable.

class My_UserController extends Zend_Controller_Action { public function indexAction() { global $application; $options = $application->getOptions(); } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.