router
router copied to clipboard
Handle DI in controller/action calls
Hi guys
I need to know about DI in instantiating controller object, how could we handle it via this package?
@mhipo1364 , are you wanting to pass params to your controller via DI? For example:
<?php
use Some\Request;
class HomeController {
public function index(Request $request) {
// $request
}
}
Closing this issue due to inactivity. I'll gladly reopen when it becomes active again.
Noticed that the PR in #76 is related to this, so reopening.
What's missing from that PR is updated documentation (~ an example) + tests
I was struggling with this as well. I use Auryn DI as well as keep a "map" of my routes that I load and wanted to add via a loop. Here is what I did.
$router = new \Bramus\Router\Router();
$routes = include('Routes.php');
foreach ($routes as $route) {
// GET/POST/PUT : my/route/pattern : [ controller, method]
list($method, $location, $callback) = $route;
match(strtolower($method)) {
'get', 'post' => $router->get($location, function(...$params) use ($callback, $injector, $response) {
$class = $injector->make($callback[0]);
if (method_exists($class, $callback[1])) {
$response->setContent(call_user_func_array(array($class, $callback[1]), $params));
}
}),
default => throw new \Exception('Invalid router parameters')
};
}
$router->run();
I don't keep get and post together as this shows, I just had it together figuring everything out. My routes are mapped as such:
return array(
array('GET', '/', ['App\Controllers\Frontpage', 'index']),
array('GET', '/login', ['App\Controllers\Login', 'index']),
array('POST', '/login/process', ['App\Controllers\Login', 'processLogin']),
array('GET', '/logout', ['App\Controllers\Logout', 'logout'])
);
Essentially, I am looping through my routes and adding them with get(), post(), etc. I don't want the router to instantiate the class, I want my DI to do so. In this case, rather than passing my controller/method callback, I used an anonymous function and a splat operator (?) to retrieve the params. From here, I could use my DI to make my class, set the response content from calling it and that's it. Note, this example is using the match operator which works only with PHP 8. You can easily change this to a switch statement to work on previous versions.
I realize this is an old issue, but I had found absolutely nothing on this when searching. This covers applying routes from an external route map, di and using a typical response object (in my case, Symfonys http foundation response).
I'm also figuring out, how I could use my DI container in a less verbose way. here is how i did it:
class dispatcher{
// app is your DI container
public static $app;
public static function __callStatic($m, $args){
list($class, $meth) = explode('__', $m);
$api = self::$app->get("api\\{$class}");
if(preg_match("/^post_/", $meth)){
$args[] = get_json_req();
}
$res = $api->$meth(...$args);
resp($res);
}
}
dispatcher::$app = $app;
$router->mount('/admin', function() use ($router) {
$router->get('/orgs', "dispatcher::orgs__get_orgs");
$router->get('/org/(\w+)', "dispatcher::orgs__get_org");
$router->post('/org/(\w+)', "dispatcher::orgs__post_create");
$router->delete('/org/(\w+)', "dispatcher::orgs__delete");
});