How to autoload Zend Framework module models?

2019-02-15 20:04发布

I am building a new CMS in Zend Framework and I don't have much exposure to ZF. Client requires two sections called Admin and FE. So, I have structured my application structure as follows.

- SITE
-- application
---- configs
---- layouts
---- modules
-------- default
------------ controllers
------------ forms
------------ models
------------ views
------------ Bootstrap.php
-------- admin
------------ controllers
------------ forms
------------ models
------------ views
------------ Bootstrap.php
---- Bootstrap.php
-- public
-- library
-- index.php

My structure is working fine and layouts and controllers are loading when I am accessing site like http://site or http://site/admin.

My question is 1.) How will I autoload my models in modules. In the model specific bootstrap file I have added below code. But it is not working.

class Admin_Bootstrap extends Zend_Application_Module_Bootstrap 
{
    protected function _initAutoload()
    {
        $autoloader = new Zend_Application_Module_Autoloader(array(
            'basePath' => APPLICATION_PATH.'/modules/admin/',
            'namespace' => '',
            'resourceTypes' => array(
                'form' => array(
                    'path' => 'forms/',
                    'namespace' => 'Form_',
                ),
                'model' => array(
                    'path' => 'models/',
                    'namespace' => 'CPModel_'
                )
            ),
        ));
        return $autoloader;
    }
}

2.) How will I use different layouts for different module?

1条回答
聊天终结者
2楼-- · 2019-02-15 20:16

Two questions here:

  1. Autoloading models
  2. Module-specific layout

For autoloading models, first make sure that your module bootstrap class extends Zend_Application_Module_Bootstrap. This will register a resource autoloader that includes a mapping so that a model class named Admin_Model_User can be stored in the file application/modules/admin/models/User.php (note the plural model*s* in the path name). For the usage you describe above, it does not appear that you need to define any such mappings yourself.

There is a bit of trickiness associated to the default module. IIRC, the default module uses the appnamespace, typically defaulting to Application_. So, for example, a user model in the default module would be named Application_Model_User and stored in the file application/modules/default/models/User.php. [If that doesn't work, then try naming Default_Model_User]

[However, if you really insist on an empty appnamespace for your admin module and a prefix of CPModel for your models - as your example suggests - then some of this changes.]

The upshot is that since most of these folders are not on the include_path, the system needs to be told at some point what class prefixes to associate/map with what directories.

For module-specific layouts, typically I create a front-controller plugin that implements the preDispatch() hook. If you keep your layouts at the top-level in application/layouts/scripts/, then your plugin can look something like the following stored in application/plugins/Layout.php:

class Application_Plugin_Layout extends Zend_Controller_Plugin_Abstract
{

    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        Zend_Layout::getMvcInstance()->setLayout($request->getModuleName());
    }
}

Register your plugin in your app-level Bootstrap, either via applications/config/application.ini:

resources.frontController.plugin.layout = "Application_Plugin_Layout"

or in the app-level Bootstrap in application/Bootstrap.php:

protected function _initPlugins()
{
    $this->bootstrap('frontController');
    $front = $this->getResource('frontController');
    $front->registerPlugin(new Application_Plugin_Layout());
}

Then, for example, your admin layout could be stored in application/layouts/scripts/admin.phtml.

查看更多
登录 后发表回答