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

"router" service name collision in hybrid Mvc/Cli app

Hi,

Buidling an MVC App, the routes are defined and stored in an Phalcon\Mvc\Router, everything good at this point : it is registred as the "router" service and used as such by several other components, the main one being the app itself

When adding a Cli part to the app, there is a cli router taking over the "router" service name. It makes sense that both are mutually exclusive for routing purpose since there can be only one point of entry to the app (Mvc app / Cli app) and so only one routing process.

In my case, I need to to generate a sitemap file from a cli task. But two different components are accessing the same "router" service, each one expecting a different object :

I have some ideas about how to make the Phalcon\Mvc\Router accessible from a Cli app but all leading to complex solutions.

  • registering it as a different service name, and let the Phalcon\Cli\Router using the "router" name
  • extending the Phalcon\Mvc\Url component to make it use this other service

Each time in a if($cli) { } else { } way. The more I go deep in it, the less it looks like a "dependency injection" pattern. Although, I'm wondering if the service name conventions shouldn't add a cliRouter service instead of sharing router for both ?

edited Feb '17

Here is the workaround I came up with

extending the Phalcon\Mvc\Url component to make it use this other service

namespace App\Lib;

class Url extends Phalcon\Mvc\Url {

  public function setRouter($router) {
    $this->_router = $router;
  }

}

registering it (Phalcon\Mvc\Router) as a different service name, and let the Phalcon\Cli\Router using the "router" name

if(!$isCli) {
    $di = new DI();
} else {
    $di = new CliDI();
}

$di->set($isCli ? 'mvcRouter' : 'router', function () use ($di, $config) {

  $router = new Phalcon\Mvc\Router(false);
  $router->setDi($di);
  $router->setUriSource(Phalcon\Mvc\Router::URI_SOURCE_SERVER_REQUEST_URI);

  // [...] routes declarations

  return $router;
});

$di->set('url', function () use ($config, $di, $isCli) {

  $url = new App\Lib\Url();

  if($isCli) {
    $url->setRouter($di->getShared('mvcRouter'));
  }

  return $url;
});

Maybe try make second $di object for url service? Its bad practice, but could work.