简体   繁体   中英

ZF2: Groups of modules

I'm in the process of learning ZF2 and planning an application.

I would like to have 1 application with several groups of modules. Each group of modules could contain up-to 20+ modules.

I won't be able to guarantee a unique name for any of the modules for the whole app, but i can guarantee their uniqueness within their module group.

Ideally route requests to module groups using a Hosting router.

eg http://admin.mysite.com/foo/ => 'Admin/Foo/Index/Index',

http://special.mysite.com/foo/ => 'Special/Foo/Index/Index'

Idea #1

I was hoping to use a different module_path for each module group and namespacing the module path around the module group to determine uniqueness of the module's class. But modules sent to the module_autoloader only seem to pay any attention to the first part of any strings passed.

eg

array('modules' => array(
 'Admin\Admin','Admin\Bob','Admin\Users'
));

This gets strange behaviour I don't understand:

  • All three will point to the correct module controller but they load the view for Admin\\Admin (which is first in the module list) instead of their own.
  • IE /users, loads Admin\\Users\\IndexController but with the view script Admin\\Admin\\view\\admin\\Index\\index.phtml

I've managed to fix this with some small alterations to the templateInjecter but it seems messy.

Idea #2

Just prefix module names to their subdirectory eg

namespace AdminAdmin\Controller,
class  IndexController {}

Thoughts

  • namespaces would be preferred to class prefixes
  • we're trying to automate as much of this as possible instead of using hardcoded routes for each module
  • it could make sense to use multiple applications that share a module for authentication via a common cookie host/memcache and db, etc...
  • route each module to a certain subdomain using the hosting type routes inside a treeRouteStack of the modules controllers etc...

Question:

  • Is their a best practice for this situation or similar and why?

My interpretation of your question is that you're really asking two questions:

(1) Namespacing modules

This is possible natively with ZF2. Modules in ZF2 are basically just PHP namespaces, so a module named Foo\\Bar is perfectly acceptable, and by default the module loader will look for it's module class in module/Foo/Bar then vendor/Foo/Bar .

For example, if you wanted to create a module Anvil and under the namespace Acme, you would create directory module/Acme/Anvil , and inside it create a Module.php file:

<?php
namespace Acme\Anvil;

class Module
{
    /* module class code goes here */
}

In your application's config/application.config.php you would add Acme\\Anvil to the modules key:

return array(
    'modules' => array(
        'Application',
        'Acme\Anvil',
    ),
    // Remaining bits of config array are unchanged
);

(2) Dynamically-loading modules

One approach you could take would be to modify your site's bootstrap index.php to modify the configuration on-the-fly based on the hostname. For example, using ZendSkeletonApplication you would set up your application.config.php file like so:

<?php
return array(
    'modules' => array(
        'Application',
        // Other modules common to all sites go here
    ),
    'sites' => array(
        'site-one.mydomain.com' => array(
            'modules' => array(
                'ModuleOne',
                'ModuleTwo',
            ),
        ),
        'site-two.mydomain.com' => array(
            'modules' => array(
                'ModuleThree',
            ),
        ),
    ),
    // Remaining bits of config array are unchanged
);

To make this work we make a slight modification to public/index.php to intercept the configuration array loaded from config/application.config.php and reconfigure the modules key:

// Pick host out of request
$hostname = $_SERVER['HTTP_HOST'];

// Load application configuration
$applicationConfig = require 'config/application.config.php';

// Merge site-specific modules into loaded modules array
$applicationConfig['modules'] = array_merge(
    $applicationConfig['modules'],
    $applicationConfig['sites'][$hostname]['modules']
);

// Run the application!
Zend\Mvc\Application::init($applicationConfig)->run();

This approach provides an easy way to change which modules are loaded for a particular hostname, but can easily be extended to allow site-specific configuration file autoloading and site-specific module directories as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM