I'm trying to sharpen up my programming skills and I came upon a frustrating problem, which will probably be best explained with an example:
Let's say I'm creating a microCMS in PHP. This microCMS has a Router class, which is responsible for routing. It also holds the URI and extra parameters that are extracted from it.
class Router{
private $uri;
private $params;
...
public function getRoute(){ ... }
...
public function getParams(){
return $this->params;
}
...
}
I also have a Front Controller, to which I'm passing a new Router() object. So far, so good, I can access the extra parameters in my Front Controller (via $router->getParams();
).
class FrontController{
private $controller;
private $view;
public function __construct(Router $router){
$route = $router->getRoute();
...
$params = $router->getParams(); //Yay, I can get to the params here!
...
$this->view = new View($route->getModel());
...
}
Now here's where it gets complicated for me. This Front Controller constructs a View. I would like this View to also be able to access the Router's functions (e.g. to be able to get the URI parameters from it).
class View{
public function output(){
//But how do I access the Router's params here...?
}
}
The first, simplest solution seems to be to make Router into a singleton or just make the function static and simply call Router::getParams()
... But that's a no no because anti-patterns.
The second, obvious solution would be to pass my Router instance to the View's constructor. I want to avoid this in fear of my constructor becoming ginormous somewhere down the line. I'm not sure how many other classes I will need to access from the View like this and I don't want them to unnecessarily clutter its constructor. Is this fear justified?
Another solution would be to use a Service Locator and call something like $serviceLocator->getRouter()
in my View. But that's, apparently, also an anti-pattern.
So what is the solution? Or is something just fundamentally wrong with my CMS' architecture?