views:

68

answers:

2

Ok here is a method I use for initializing models in my controller actions:

protected $_tables = array();

protected function _getTable($table)
{
    if (false === array_key_exists($table, $this->_tables)) {
        include APPLICATION_PATH . '/modules/'
        . $this->_request->getModuleName() . '/models/' . $table . '.php';
        $this->_tables[$table] = new $table();
        echo 'test ';
    }
    return $this->_tables[$table];
}

Then when I call the _getTable() method two times (for example once in init() method and once in the controller action) it prints:

test test test test test test

On top of the page. Shouldn't it just return the object from the _tables array() because of the array_key_exists() check? In other words shouldn't the part inside the array_key_exists() function get executed only once when the method is called multiple times?

UPDATE:

So the problem is this - for some reason the layout gets printed twice (so it's layout printed and inside the layout where there is layout()->content; ?> it prints the layout again). I have no idea why it does this as it worked well on the previous server and also on localhost.

+3  A: 

In the snippet you show:

protected $this->_tables = array();

This is not valid syntax, it should be:

protected $_tables = array();

Also, why not just use include_once and let PHP handle this for you? Alternatively, you could use the Zend_Loader. Don't reinvent the wheel.

hobodave
+1  A: 

What you are really looking for is the loading of module based resources. Instead of re-inventing the wheel, why not just use the (module) resource autoloaders of ZF? See the documentation at:

http://framework.zend.com/manual/en/zend.loader.autoloader-resource.html

When you use Zend_Application (I'm assuming you don't), you get these automatically. If you don't you could do something like

$loaders = array();
$frontController = Zend_Controller_Front::getInstance();

foreach($frontController->getControllerDirectory() as $module => $directory) {

    $resourceLoader = new Zend_Application_Module_Autoloader(array(
        'namespace' => ucfirst($module) . '_',
        'basePath'  => dirname($directory),
    ));

    $resourceLoader->addResourceTypes(array(
        'table' => array(
            'path'      => 'models/',
            'namespace' => 'Table'
    ));

    $loaders[$module] = $resourceLoader;
}
//build array of loaders

$loader = Zend_Loader_Autoloader::getInstance();
$loader->setAutoloaders($loaders);
//set them in the autoloader        

This approach is a bit naive, but it should give you nice autoloading.

naneau
I actually use the Zend_Application but instead of Zend_Loader I use native php __autoload() function like this function __autoload($class) { include str_replace('_', '/', $class) . '.php';}. Anyways, I have already figured the problem, there was a controller plugin that was interferring and causing all the trouble, it works now :)
Richard Knop