We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Dispatcher doesn't match my controller and action

Hi folks !

I'm new to Phalcon and I'm stuck with my router. It does give me the action and controller name, but the dispatcher doesn't link the controller and the action (always the default route).

I don't really know why ;(

Please help me.

my dispatcher:


$di->set(
    'dispatcher',
    function () use ($di) {
        $eventsManager = new EventsManager;
        /**
         * Handle access control list using SecurityPlugin
        */
        $eventsManager->attach('dispatch:beforeDispatch', new Security);
        $eventsManager->attach("dispatch:beforeException", function($event, $dispatcher, $exception) {
            //Handle 404 exceptions
            if ($exception instanceof \Phalcon\Mvc\Dispatcher\Exception) {
                $dispatcher->forward(array(
                    'controller' => 'errors',
                    'action' => 'show404'
                ));
                return false;
            }

            //Handle other exceptions
            $dispatcher->forward(array(
                'controller' => 'errors',
                'action' => 'show503'
            ));

            return false;
        });

        $dispatcher = new Dispatcher;
        $dispatcher->setEventsManager($eventsManager);

        return $dispatcher;
    }
);

and my router :


use Phalcon\Mvc\Router;

$router = new Router(false);
$router->add(
    "/",
    [
        "controller" => "index",
        "action"     => "index",
    ]
);
$router->add(
    "/users/login",
    [
        "controller" => "users",
        "action"     => "login",
    ]
);

$router->handle($_SERVER['REQUEST_URI']);
return $router;

Thanks a lot guys !

Please edit and format your code :)

edited Dec '16

Have you add router to your di:

$di->set('router', require BASE_DIR . '/pathto/router.php');

Also you can put aside dispatcher events for a while and check how router handles example routes.

<?php // These routes simulate real URIs
$testRoutes = [
    '/',
    '/index',
    '/index/index',
    '/users/login',
    '/users'    
];

// Testing each route
foreach ($testRoutes as $testRoute) {

    // Handle the route
    $router->handle($testRoute);

    echo 'Testing ', $testRoute, '<br>';

    // Check if some route was matched
    if ($router->wasMatched()) {
        echo 'Module: ', $router->getModuleName(), '<br>';
        echo 'Controller: ', $router->getControllerName(), '<br>';
        echo 'Action: ', $router->getActionName(), '<br>';
    } else {
        echo 'The route wasn\'t matched by any route<br>';
    }

    echo '<br>';
}

die;

?>

And finally I'm not sure you need $_SERVER['REQUEST_URI'] in router handle



1.3k
edited Dec '16

First, thanks a lot for your quick answers

@Nikolay Mihaylov I don't understand, i used the '''php to insert my code.

@JaySJay I already did the test for routes, and everything seems to work pretty well. But it don't do the action called in the controller called.

Testing / Module: Controller: index Action: index

Testing /index The route wasn't matched by any route

Testing /index/index The route wasn't matched by any route

Testing /users/login Module: Controller: users <- It does not the loginAction in my UsersController Action: login

Testing /users The route wasn't matched by any route

I forgot to mention that I use a nginx server (I don't know if it can have an impact).

When I remove in my router :

$router->add(
    "/",
    [
        "controller" => "index",
        "action"     => "index",
    ]
);

and add :

$router->notFound(array('controller' => 'errors', 'action' => 'show404'));

I get only 404 even with the others matching routes... At least this time it link with correct controller et action ! (o_0' )

Maybe this post is related with this one : https://forum.phalcon.io/discussion/514/nginx-routing-problem

I give you my nginx conf


server {
  listen *:80;
  server_name           dev.test.fr preprod.test.fr test.fr;

  index  index.php;

  access_log            /srv/log/nginx/test.access.log combined;
  error_log             /srv/log/nginx/test.error.log;

  location / {
    root      /srv/www/wimmo/htdocs/public;
    index     index.php;
    try_files $uri $uri/ /index.php?$args;
  }

  location ~ \.php$ {
    root          /srv/www/wimmo/htdocs/public;
    include       /etc/nginx/fastcgi_params;
    try_files     $uri =404;

    fastcgi_pass  phpupstream;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  }
}

Sorry, I'm not good at nginx setup. But, yes, it could be due web server setup, and having your url rewriten incorrectly can cause router fail to process it. To ckeck this you can echo/dump $_SERVER['REQUEST_URI'] straight from your router, before processing it. It should be exactly/users/login if you going dev.test.fr/user/login.



1.3k

Yeah i got 'REQUEST_URI' => string '/users/login' (length=12) that why i put $router->handle($_SERVER['REQUEST_URI']); in my router

edited Dec '16

Hm. I'm not sure, but I think you shoud try

$router->handle();

instead of

$router->handle($_SERVER['REQUEST_URI']);

also try to comment out

$eventsManager->attach('dispatch:beforeDispatch', new Security);

I don't know what you have in your Security class, but it potentially can stop dispatcher from transfering request to required controller. (Also I wonder why you call contructor without brackets).



1.3k

Thanks @JaySJay Allright I tried everything, still the same result ...

edited Dec '16

I'm almost ran out of ideas. Maybe you could try attach this event to your dispatcher(instead of all the others):

$eventsManager->attach("dispatch:beforeExecuteRoute", function($event, $dispatcher, $exception) {
            echo($dispatcher -> getControllerName());
            echo('</br>');
            echo($dispatcher -> getActionName());
            die;
        });

If it echoing your controller and action than it founds corresponding class and function, if not - something wrong with your loader/namespaces.



1.3k
edited Dec '16

It give me index index ;( even if i am on /users/login

I dump the event in the beforeExecuteRoute attachment And it find a matched Route.

I don't know on what source it does the matches. Even if I use $router->handle($_SERVER['REQUEST_URI']); protected '_matchedRoute' => object(Phalcon\Mvc\Router\Route)[55] protected '_pattern' => string '/' (length=1) protected '_compiledPattern' => string '/' (length=1) protected '_paths' => array (size=2) 'controller' => string 'index' (length=5) 'action' => string 'index' (length=5)



1.3k

Oh guys I found the problem !

It's in the nginx conf:

location / { root /srv/www/wimmo/htdocs/public; index index.php; try_files $uri $uri/ /index.php?_url=$uri&$args; }

I add the _url and it worked !

Thanks for your help @JaySJay !

edited Dec '16

Not at all. You solved it yourself.

Yep, we should have checked $router->getRewriteUri() in router instead of $SERVER[REQUEST_URI] to figure something was wrong in web server config. $SERVER[REQUEST_URI] is always equal to initially requested path.