I usually do it this way:
Collection - The collection that will store all routes.
Route - The class that represents a route. You must provide information like the Uri you want to capture and http verbs accepted.
Router - The class that serves to bridge the gap between Route and Collection. It is a facilitator to create routes within the collection.
Dispatcherinterface - The interface that provides a method to be executed as the route dispatcher. I preferred to make an interface to be able to meet several implementations, for example, someone who wants to use a more complex library or who simply wanted to use less resources.
So in that context, we would have a structure something like this:
$router = new Router(new Collection);
// Cria a instância de Route, coloca dentro da Collection
// E retorna Rota recém-criada, para possíveis outra definições
$router->get('/', 'HomeController::getIndex');
$router->get('/login', function () {})->setName('home.login');
// Classe que implementa DispatcherInterface
$router->dispatch(new Dispatcher());
Based on the context presented in the question, I think an interesting one would be:
$request = new Request();
// retorna new Response se tudo der certo
$response = $router->dispatch(new RequestDispatcher($request));
$response->send();
Within your RequestDispatcher
, you could apply the proper operations to call Controller and Method.
For example:
class RequestDispatcher implements DispatcherInterface {
public function __construct(Request $request) {
$this->request = $request;
}
public function dispatch(Router $router) {
$route = $router->findByRequest($this->request);
if (! $route) return $this->notFound();
$response = call_user_func($route->callAction(), $route->getParameters());
return $response;
}
}
That is, in your Dispatcher, you can add the operations needed to search for the route within the collection. When not found, you can invoke an action to lasso the 404 error. When it is found, you can call the action set to the given url and call it, then return a Response.
Trying to sum it up:
Dispatcher searches the route within a collection of routes, which was created by the router. Then, if Dispatcher finds the route, it converts the return of the route action (Can be a Controller method or a Closure) to a Response, which is finally sent to the output.
You quoted in your question regarding a Handler, which is passed through a callback.
I believe you are talking about an anonymous function, which some libraries use to "tie" a certain functionality to a route in order to run at the end.
In my library I also did this. I can use both a class method (the Controller) and an anonymous function. I think this is very useful in cases where the route does not make sense to point to a specific controller, because it is not something that does not have "relationship" with the rest.
Example:
$router->get('/json/cep/{num}', function ($number) {
$url = sprintf('https://cep.correios.com.br/%s.json', $number);
$dados = json_decode(file_get_contents($url));
// Transforma em JsonResponse
return $dados;
});
This question may help you > http://answall.com/questions/60830/quando-o-controller%C3%A9-necess%C3%A1rio
– LucaoA
Thanks Lucaoa, it sure will help a lot. : D
– KaduAmaral
The routes are usually run by a "Dispatcher", who is the guy responsible for Dispachar’s request. Take a look at the framework I played Phplegends/Maxters. It uses components that are installed via Composer, among them the Phplegends/Routes
– Wallace Maxters
It’s not jabá! take a look at example
– Wallace Maxters