views:

49

answers:

3

Maybe I've been staring at the problem too long and it's much simpler than I think, but I'm stuck right now.

I have three websites that are going to share database models. I've structured my applications so that I have an application directory for each site and a public directory for each site. The DB models live in a directory in the library along with Zend Framework and my third party libraries. I use the Autoloader class and when I try to instantiate one of my DB classes, it fails. The library directory is in my include path, but for whatever reason it refuses to instantiate my classes.

It will work if I have my models in my application directory, but that's not the point. They're supposed to be shared classes in a Library.

$model = new Model_Login();
$model->hello_world();

This fails when its in the library. The class is just a test:

 class Model_Login
 {
     public function hello_world()
     {
        echo "hello world";
     }
 }

Everything works until I try to instantiate one of my models. I've even tried renaming the class to something else (Db_Login), but that doesn't work either. Any ideas? Thanks in advance.

Autoloader from the Bootstrap:

$autoloader = new Zend_Application_Module_Autoloader(array(
       'namespace' => '',
       'basePath'  => dirname(__FILE__),
));
+1  A: 

I would use the library directory to store all those models. That dir can be shared by all sites.

I have the following Dir:

application

  • configs

  • models

  • controllers

  • views

library

  • Myns

  • Zend

public

and my config i have:

includePaths.library = APPLICATION_PATH "/../library"
autoloaderNamespaces.Myns = Myns_

that allows me to store files in Myns and call: Myns_Login

MANCHUCK
That's what I'm trying to do, but the autoloader isn't playing nicely. Can't figure out why.
jeffkolez
The autoloader will not automatically set up the namespace. after declaring the library in you config, add the autoloaderNamespaces directive: autoloaderNamespaces.Myns = Myns_
MANCHUCK
Shouldn't it be a matter of pointing the auto-loader at the right directory? I'm not sure I understand how namespaces fit in here.
jeffkolez
I'm overthinking. Don't I just need to add a directive in my application.ini to change the path I look for my models? How do I even do that?
jeffkolez
+3  A: 

In your bootstrap use

 protected function _initAutoload() {

    $autoloader = new Zend_Application_Module_Autoloader(array(
                'namespace' => 'Default_',
                'basePath' => dirname(__FILE__),
            ));
    $autoloader->addResourceType('models', 'models/', 'Models');
    return $autoloader;
}

Then just name your objects:

$model = new Default_Models_Login();
$model->hello_world();
Iznogood
You can also set namespace to an empty string if you prefer not to use one and just call the models as Model_Login
Mark
@Mark: Indeed. I am so used to having modules I just forget that. Thanks!
Iznogood
+1  A: 

Okay, you're using the module autoloader in your bootstrap. It's designed to be used in module bootstraps, as it searches just one directory tree (usually a specific directory in application/modules), rather than using the include path. It can be used in the main bootstrap as an autoloader for the default module, which is why your class worked when you put it in application/models.

I think you want to switch to using the standard autoloader.

I'm assuming in your bootstrap class you currently have something like this:

protected function _initAutoloader()
{
    $autoloader = new Zend_Application_Module_Autoloader(array(
        'namespace' => '',
        'basePath'  => dirname(__FILE__),
    ));

    return $autoloader;
}

change it to this:

protected function _initAutoloader()
{
    $autoloader = Zend_Loader_Autoloader::getInstance();
    $autoloader->setFallbackAutoloader(true);

    return $autoloader;
}

this sets up the autoloader (which will also by default setup autoloading for the Zend Framework classes) and then tells it to use this autoloader for any namespace not matched by another (because your class has no namespace). With this approach you can drop any class using the PEAR naming conventions into your library directory and use it in your code.

Alternatively you could do:

protected function _initAutoloader()
{
    $autoloader = Zend_Loader_Autoloader::getInstance();
    $autoloader->registerNamespace('Model');

    return $autoloader;
}

which sets up the autoloader and then tells it to use this autoloader for the namespace 'Model', which will match your Model_Login class.

Tim Fountain
Yep - that did the trick - thanks!
jeffkolez