8

After searching a long time with no success. before I give up, I would like to ask:

Is there a way to route a subdomain to a module in Zend Framework 2? like:

Subdomain => Module
api.site.com => api
dev.site.com => dev
admin.site.com => admin
site.com => public
...

I tried doing it like this but I can't get access to controllers other than the default (Index).

'router' => array(
    'routes' => array(
        'home' => array(
            'type' => 'Hostname',
            'options' => array(
                'route' => 'site.com',
                'defaults' => array(
                    '__NAMESPACE__' => 'Application\Controller',
                    'controller'    => 'Index',
                    'action'        => 'index',
                ),
            )
        )
    ),
),

Thank you for taking the time to help me.

severin.julien
  • 1,314
  • 15
  • 27

2 Answers2

5

Zend Framework 2 doesn't have a notion of routing to modules; all routing mappings are between a URI pattern (for HTTP routes) and a specific controller class. That said, Zend\Mvc provides an event listener (Zend\Mvc\ModuleRouteListener) which allows you to define a URI pattern that maps to multiple controllers based on a given pattern, and so emulates "module routing". To define such a route, you would place this as your routing configuration:

'router' => array(
    'routes' => array(
         // This defines the hostname route which forms the base
         // of each "child" route
        'home' => array(
            'type' => 'Hostname',
            'options' => array(
                'route' => 'site.com',
                'defaults' => array(
                    '__NAMESPACE__' => 'Application\Controller',
                    'controller'    => 'Index',
                    'action'        => 'index',
                ),
            ),
            'may_terminate' => true,
            'child_routes' => array(
                // This Segment route captures the requested controller
                // and action from the URI and, through ModuleRouteListener,
                // selects the correct controller class to use
                'default' => array(
                    'type'    => 'Segment',
                    'options' => array(
                        'route'    => '/[:controller[/:action]]',
                        'constraints' => array(
                            'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
                            'action'     => '[a-zA-Z][a-zA-Z0-9_-]*',
                        ),
                        'defaults' => array(
                            'controller' => 'Index',
                            'action'     => 'index',
                        ),
                    ),
                ),
            ),
        ),
    ),
),

(Click here to see an example of this @ ZendSkeletonApplication)

This is only half of the equation, though. You must also register every controller class in your module using a specific naming format. This is also done through the same configuration file:

'controllers' => array(
    'invokables' => array(
        'Application\Controller\Index' => 'Application\Controller\IndexController'
    ),
),

The array key is the alias ModuleRouteListener will use to find the right controller, and it must be in the following format:

<Namespace>\<Controller>\<Action>

The value assigned to this array key is the fully-qualified name of the controller class.

(Click here to see an example of this @ ZendSkeletonApplication)

NOTE: IF you aren't using ZendSkeletonApplication, or have removed it's default Application module, you will need to register the ModuleRouteListener in one of your own modules. Click here to see an example of how ZendSkeletonApplication registers this listener

Adam Lundrigan
  • 598
  • 2
  • 11
  • 2
    Thank you very much for the explanations clear and precise. I took your solution. I struggled so much on this. – severin.julien Oct 25 '12 at 17:01
  • i use mamp pro and i create a subdomain on my virtual host name so after i use reseller.myhost.com/test it is okey but if i write reseller.myhost.com it goes to index of application not indexaction of my module – babak faghihian Jun 29 '15 at 07:57
  • @Sapher but why other routes of other modules work yet on current subdomain ? – babak faghihian Jun 30 '15 at 06:47
4

If i understand slide #39 of DASPRIDS Rounter Presentation correctly, it's as simple as - on a per module basis - to define your subdomain hosts, i.e.:

'router' => array(
    'routes' => array(
        'home' => array(
            'type' => 'Hostname',
            'options' => array(
                'route' => 'api.site.com',
                'defaults' => array(
                    '__NAMESPACE__' => 'Api\Controller',
                    'controller'    => 'Index',
                    'action'        => 'index',
                ),
            )
        )
    ),
),

Etc, you'd do this for every Module on its own.

Sam
  • 16,435
  • 6
  • 55
  • 89