What is the difference between Phalcon\Mvc\Router::setDefaults() and Phalcon\Mvc\Router::notFound()? Both of them sets an array of default paths the router will use if route is missing.
|
Sep '14 |
5 |
4600 |
5 |
What is the difference between Phalcon\Mvc\Router::setDefaults() and Phalcon\Mvc\Router::notFound()? Both of them sets an array of default paths the router will use if route is missing.
May be this is it: "Since none route is matched the router passes empty values to the dispatcher, and the dispatcher is using the default controller/index to address the request. In 1.0.0 you can set what paths must be used if none existing route is matched:
$router->notFound(array('controller' => 'errors', 'action' => 'notfound404'));
https://github.com/phalcon/cphalcon/issues/446#issuecomment-14251200
The new 'not-found paths' is different to defaults. 'Defaults' is intended to fill paths that aren't defined in every route added to the router:
$router = new Phalcon\Mvc\Router(false);
$router->setDefaultNamespace('App\Controllers');
$router->add('/app/index', array(
'controller' => 'index',
'action' => 'index'
));
$router->add('/app/robots', array(
'controller' => 'robots',
'action' => 'index'
));
Both routes have by default the namespace App\Controllers without explicitly set them manually. Consider the following example, where 'defaults' are used as 'not found' routes:
$router = new Phalcon\Mvc\Router(false);
$router->setDefaults(array(
'controller' => 'errors',
'action' => 'notFound404'
));
$router->add('/index', array(
'module' => 'frontend',
'controller' => 'index',
));
$router->add('/admin/index', array(
'module' => 'backend',
'controller' => 'index'
));
The path 'action' is not defined because we expect to use the default 'index', but as we're using the defaults it will fill it with 'notFound404' instead of 'index', so when we access /index the paths returned by the router will be: module => frontend, 'controller' => 'index', 'action' => 'notFound404' that is wrong.
This is fixed using the notFound method:
$router = new Phalcon\Mvc\Router(false);
$router->notFound(array(
'controller' => 'errors',
'action' => 'notFound404'
));
$router->add('/index', array(
'module' => 'frontend',
'controller' => 'index',
));
$router->add('/admin/index', array(
'module' => 'backend',
'controller' => 'index'
));
Note that notFound method is not a final solution for a 'not-found' handler, Let's pretend we define the following routes:
$router = new Phalcon\Mvc\Router(false);
$router->add('/:controller', array(
'module' => 'frontend',
'controller' => 1
));
$router->add('/:controller/:action/:params', array(
'module' => 'frontend',
'controller' => 1,
'action' => 2,
'params' => 3
));
These routes match almost every URI passed to the application, there're no way that the router doesn't match a route if they're defined in this way, so implement 'notFound' paths are useless here.
If /products/save/1 is passed as route it passes {controller => products, action => save, params => [1] }
The dispatcher needs to execute the route but it couldn't exists, so that's why you need to implement a notFound handler in the dispatcher:
$eventsManager->attach("dispatch", function($event, $dispatcher, $exception) {
if ($event->getType() == 'beforeException') {
switch ($exception->getCode()) {
case Phalcon\Dispatcher::EXCEPTION_HANDLER_NOT_FOUND:
case Phalcon\Dispatcher::EXCEPTION_ACTION_NOT_FOUND:
$dispatcher->forward(array(
'controller' => 'errors',
'action' => 'show404'
));
return false;
}
}
});