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

Issue with short syntax and Phalcon\Mvc\Router\Group

I'm trying to use the short syntax when adding routes inside a router group. The router matches the route properly but the controller name and action name come back as null.

Do router groups not support the same short syntax as the router?

class Routes extends Phalcon\Mvc\Router\Group
{
    public function initialize()
    {
        $this->add('/posts', 'Post::index');
    }
}

$router->mount(new Routes);
$router->handle();

var_dump( $router->getControllerName() );


98.9k

This example is giving me: string(4) "post"

class Routes extends Phalcon\Mvc\Router\Group
{
  public function initialize()
  {
    $this->add('/posts', 'Post::index');
  }
}

$router = new Phalcon\Mvc\Router(false);
$router->mount(new Routes);
$router->handle('/posts');

var_dump( $router->getControllerName() );

Sorry my bad. I've narrowed down whats triggering the problem. When you set the namespace using setPaths() then the short syntax no longer works.

class Routes extends Phalcon\Mvc\Router\Group
{
    public function initialize()
    {
        $this->setPaths([
            'namespace' => 'Ds\Backend\Controllers',
        ]);
        $this->add('/posts', 'Post::index');
    }
}

$router = new Phalcon\Mvc\Router(false);
$router->mount(new Routes);
$router->handle('/posts');

var_dump( $router->getControllerName() );


98.9k

This works:

<?php

class Routes extends Phalcon\Mvc\Router\Group
{
  public function initialize()
  {    
    $this->add('/posts', 'Db\Backend\Controllers\Post::index');
  }
}

$router = new Phalcon\Mvc\Router(false);
$router->mount(new Routes);
$router->handle('/posts');

var_dump( $router->getNamespaceName() );
var_dump( $router->getControllerName() );

Rather than having the short syntax assume the global namespace wouldn't it make more sense if it operated as follows:

preg_match('/^(?<namespace>.*\\\\?)(?<controller>[^\\\\]+)::(?<action>.+)$/U', 'Db\Backend\Controllers\Post::index', $matches);
print_r($matches);

preg_match('/^(?<namespace>.*\\\\?)(?<controller>[^\\\\]+)::(?<action>.+)$/U', 'Post::index', $matches);
print_r($matches);

/*

Array
(
    [0] => Db\Backend\Controllers\Post::index
    [namespace] => Db\Backend\Controllers\
    [1] => Db\Backend\Controllers\
    [controller] => Post
    [2] => Post
    [action] => index
    [3] => index
)

Array
(
    [0] => Post::index
    [namespace] => 
    [1] => 
    [controller] => Post
    [2] => Post
    [action] => index
    [3] => index
)

*/

The set the namespace only if found in the short syntax. This way it would respect the default namespace for the group if it has been set.