简体   繁体   中英

How do I inject a request into a facade class in Laravel?

So I have the following class that's a facade:

namespace App\Helpers;

use App\Http\Requests\HomepageRequest;

class Params {

    public function __construct(HomepageRequest $request) {

    }

Then I have the ParamsServiceProvider class which instantiates the facade class on script startup:

public function register()
{
    //
    App::bind('params', function() {
        return new Params();
    });
}

edit: here is the actual facade for the Params class

use Illuminate\Support\Facades\Facade;

class Params extends Facade {
    protected static function getFacadeAccessor() {
        return 'params';
    }
}

This all works fine, the class is instantiated properly, however, it doesn't seem to inject the request object in the constructor like it would in a controller class. Is there a way to inject the request into a facade class like you would in a controller? With the current code, I get the following error:

Too few arguments to function App\\Helpers\\Params::__construct(), 0 passed in /var/www/v4api/html/app/Providers/ParamsServiceProvider.php on line 21 and exactly 1 expected

I want to avoid having to manually pass the request input into the class and just have it automatically be injected in the constructor. Any help that you guys can give would be appreciated!

Looks like this worked out:

In the ParamsServiceProvider, instead of using App::bind to instantiate the Params class, do this instead:

public function register()
{
    App::alias(Params::class, 'params');
}

then the request object will be injected properly into the facade.

The class you've posted isn't actually a Facade - it's just a regular class.

Because you've type-hinted it's dependencies you don't need to tell Laravel how to create an instance of it - it can work it out all by itself.

You can either inject that class into a controller method (where Laravel will new it up for you), or you can call app(App\\Helpers\\Params::class) and it will return a new instance of the class for you.

Read more on creating facade classes if you want to create an actual facade. Alternatively you can create a realtime facade - where you instead reference Facades\\App\\Helpers\\Params::foo() and Laravel will let you use the method as if you had an instance of that class.

You have a number options here - point the facade straight to the underlying class and let Laravel work out how to build it, explicitly bind it to the container, or use a realtime facade. Let's go through each.

class Params extends Facade 
{
    protected static function getFacadeAccessor() 
    {
        return \App\Helpers\Params::class;
    }
}

This option points the facade straight to the class you intend it to be a facade for and Laravel will work out the rest.

Alternatively, you can keep it as params and instead fix the binding in the container.

The first example use's Laravel's container to make an instance of the class and return it. Laravel can automatically reflect the class and inject it's dependencies.

App::bind('params', function ($app) {
    return $app->make(Params::class);
});

The second example explicitly builds the instance the way you desire, which is just additional code for you to maintain.

App::bind('params', function() {
    return new Params(new HomepageRequest);
});

The final option - as mentioned in the earlier answer - is to use a realtime facade and skip the manual binding entirely. You can learn more about realtime facades in the docs .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM