Search code examples
zend-framework3

ZF3 advanced routing - With HTTP method


I'm Creating one site with ZF3. I'm having troubles whith some Route.

For sample,

I expected When I access this URL : http://localhost/customer-import/ , if POST method : CustomerImportController::Process will be execute , if GET method : CustomerImportController::Index will be execute

Actually: Always CustomerImportController::Index has been executed

Config file:

'router' => [
        'routes' => [
            'customers' => [
                'type'    => Segment::class,
                'options' => [
                    'route'    => '/customers',
                    'defaults' => [
                        'controller' => Controller\CustomerController::class,
                        'action'     => 'index',
                    ],
                ],
            ],
            'customers-import' => [
                'type'    => Literal::class,
                'options' => [
                    'route'    => '/customer-import-tool',
                    'defaults' => [
                        'controller' => Controller\CustomerImportController::class,
                        'action' => 'index',
                    ],
                ],
                'may_terminate' => true,
                'child_routes' => [
                    'import_customer' => [
                        'type' => Method::class,
                        'options' => [
                            'verb' => 'post',
                            'defaults' => [
                                'controller' => Controller\CustomerImportController::class,
                                'action' => 'import',
                            ],
                        ],
                    ],
                ],
            ],
        ],
    ],

What am I doing wrong?


Solution

  • You always end up in CustomerImportController::Index (-> customers-import route) because it isn't specified that it must get matched only for GET requests. You are hitting the same url (host/customer-import-tool), but you declared only the POST subroute.. except that both POST and GET are matched before.

    The solution here is quite simple: - you declare the main literal route, but it doesn't have a dispatcher - you declare the two method subroutes, one for GET and one for POST

    'customers-import' => [
        'type'    => Literal::class,
        'options' => [
            // Here you specify the literal route
            'route'    => '/customer-import-tool',
            'defaults' => [
                'controller' => Controller\CustomerImportController::class
            ],
        ],
        // Here you specify that "customer-import" can't be dispatched by itself,
        // but only by its childs
        'may_terminate' => false,
        'child_routes' => [
            // Here you match GET requests to the literal parent
            'get_import_customer' => [
                'type' => Method::class,
                'options' => [
                    'verb' => 'get',
                    'defaults' => [
                        'controller' => Controller\CustomerImportController::class,
                        'action' => 'index'
                    ]
                ]
            ],
            // Here you match POST requests to the literal parent
            'post_import_customer' => [
                'type' => Method::class,
                'options' => [
                    'verb' => 'post',
                    'defaults' => [
                        'controller' => Controller\CustomerImportController::class,
                        'action' => 'import'
                    ]
                ]
            ]
        ]
    ],