Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constructor injection of route parameter

I have a class which I am injecting into a controller along with a route parameter. I am then using a setter to set the route parameter in the class.

routes

Route::get('path/of/url/with/{paramVar}', 'testController@testFunc)

controller

class testController
{
    public function testFunc(MyClassInterface $class, $routeParamVar)
    {
        $class->setParam($routeParamVar);
        //do stuff here
        ...

service provider

public function register()
{
    $this->bind('path\to\interface', 'path\to\concrete');
}

I would instead like to inject the route parameter into the constructor of the class I am injecting into my controller. I know from this question that I need to use the laravel container.

I can inject other route parameters using Request::class, but how can I inject the route path parameter?

I guess I would end up with something like this

class testController
{
    public function testFunc(MyClassInterface $class)
    {
        //do stuff here
        ...
like image 290
myol Avatar asked Feb 08 '16 09:02

myol


1 Answers

You can use the $router->input('foo') function to retrieve a route parameter within your service container.

https://laravel.com/api/master/Illuminate/Routing/Router.html#method_input

So in your service provider:

public function register()
{
    $this->bind('path\to\interface', function(){

        $param = $this->app->make('router')->input('foo');

        return new path\to\concrete($param);

    });
}

In regards to your comment, it wouldn't reduce the code much, but it might be best in that case to make a second service provider, something like FooValueServiceProvider who's implementation's only job is to retrieve that parameter from the router. Then in each of the bindings you could resolve a FooValueServiceProvider and retrieve the value from that. Then later if you change the name of the route param, or need to resolve it from somewhere other than the route, you only need to change out the implementation of that provider.

I don't know if you can get much more efficient than just the one extra line of code per binding, but at least this way it can be changed out for a different method down the line.

like image 94
Jeff Avatar answered Sep 24 '22 14:09

Jeff