Ally
Ally

Reputation: 955

Phalcon php router notFound not working

I'm just bashing about with Phalcon right now, trying to get my head around it as I'm thinking of porting a big project from CodeIgniter to Phalcon or another framework before development continues any further.

I'm using the router to try and catch 404 errors, but this is not working as expected. The router it's self seems to be working as I also have $router->add("/" to fetch the site index controller if index.php is not defined, and if I comment that out, going to home/ then throws a 404! However, typing in some non existent controller name e.g. test, gives me the error "PhalconException: TestController handler class cannot be loaded". My htaccess is as per the Phalcon docs tutorials.

In the bootstrap (index.php) I have;

$di->set('router', function() { require __DIR__ . '/../app/config/routes.php'; return $router; });

And my routes.php looks like this;

$router = new \Phalcon\Mvc\Router();

// default
$router->add("/", array(
    'controller' => 'index',
    'action' => 'index'
));

//Set 404 paths
$router->notFound(array(
    "controller" => "group",
    "action" => "index"
));

$router->handle();
return $router;

The site has user submitted groups that are reached by domain.com/group-name/ In CI I was using a 404 rout to load the group controller which would activate a search for that group. If found it would display the group and if not it would throw a 404 page with 404 headers. It may well be that there's a better way of doing that in Phalcon, but I would at least love to know why my notFound rout is failing to work ;)

EDIT: Not sure if this changes anything, but I am using a base controller "controllerBase" which all main controllers are extending. It just contains some vars and an initialize function and another function that can be called from controllers. I wouldn't have thought this would effect the notFound routing, but thought I better mention it any way.

Upvotes: 2

Views: 9258

Answers (3)

jpaylor
jpaylor

Reputation: 106

The default behavior of \Phalcon\Mvc\Router does not make use of the notFound() method.

If you'd like to use notFound(), you need to disable the default routes first as described here: http://docs.phalconphp.com/en/latest/reference/routing.html#default-behavior

In your example, you simply need to change:

$router = new \Phalcon\Mvc\Router();

to the following:

$router = new \Phalcon\Mvc\Router(false);

Upvotes: 8

Ian Bytchek
Ian Bytchek

Reputation: 9075

Don't you have a feeling this must be the other way around? I'd say if you have routes like domain.com/group-name/ they must be handled like routes, not like 404s… Only when the group is not found the application should respond with a 404. Sounds simpler and more logical.

$router = new \Phalcon\Mvc\Router();

// group - match any 1+ characters
$router->add("/(.+)", array(
    'controller' => 'group',
    'action' => 'index',
    'params' => 1
));

// default
$router->add("/", array(
    'controller' => 'index',
    'action' => 'index'
));

// action in group controller
public function indexAction($group) {
    if ($this->groupExists($group)) {
        // display it
    } else {
        $this->dispatcher->forward([
            'action'     => 'error404',
            'controller' => 'error'
        ]);
    }
}

// action in error controller
public function error404() {
    // …
    // dispay the error
    // …

    $this->response->setStatusCode(404, 'Not Found');
}

Ideally you'd have a better mechanism for handling 404s, so you could just throw new NotFoundException(); and not manage headers in the action. And don't forget about the routes order: since you can add many routes as you need using add(), the order in which routes are added indicate their relevance, latest routes added have more relevance than first added.

With regards to $router->notFound() not working it smells like something simple is missing – did you triple check the names / paths / order when things are called?

Upvotes: 2

David Duncan
David Duncan

Reputation: 1858

It looks to me like you are calling $router->handle() too early.

It helps to check out how other projects have accomplished the same thing: https://github.com/phalcon/forum/blob/master/app/config/routes.php

bootstrap:

$di->set(
    'router',
    function () {
        return require __DIR__ . '/../app/config/routes.php';
    },
    true
);

routes:

$router = new \Phalcon\Mvc\Router();

// default
$router->add("/", array(
    'controller' => 'index',
    'action' => 'index'
));

//Set 404 paths
$router->notFound(array(
    "controller" => "group",
    "action" => "index"
));

return $router;

bootstrap again :

... end of file ...


echo $application->handle()->getContent();

Upvotes: 1

Related Questions