Override a core Laravel 4 class method

后端 未结 2 1315
無奈伤痛
無奈伤痛 2021-02-10 02:19

Apologies if this is a dumb question as a lot of Laravel 4 is new to me. I\'m trying to override a couple of the methods in the core password functionality as I want to define m

相关标签:
2条回答
  • 2021-02-10 03:11

    The previous answer here is generally correct but doesn't really do enough to explain what's going on, so I'll give it a go.

    Suffice it to say that any facade method access is generally done statically, so if you define a (public) method on a facade you should ensure it's a static one. However, facades are actually, well, facades for an underlying non-static class, using magic methods to pass a static call on the facade to an instance method on the underlying class. As such, you generally wouldn't want to extend a facade by defining a static method on one but instead define an instance method on the underlying class. In the case of the Password facade, the underlying class is an instance of PasswordBroker. This underlying class dealio is generally set up by registering an instance on the IoC container, and then in the facade you define a getFacadeAccessor method on the facade class which returns the IoC key in which to find the instance. (In the case of the Password facade, the IoC key is auth.reminder.)

    This is where a problem comes in for you though, because you can't just override a Laravel core class. The most correct thing to do is to probably extend PasswordBroker and then set your version of the class up as the key in the IoC that the Password facade normally uses (auth.reminder). That way, your added method will be available on the facade, btu anything else will still defer to the original PasswordBroker class.


    You'll notice that you don't have to create a new facade, but just override the existing facade's IoC key. When to do this can be a bit of a tricky one. If you are not using your own service provider, and do this stuff in routes.php or something, then you're probably safe. However, if you are using a service provider to modify this Password behaviour, you can't (shouldn't) actually rely on the order of Laravel's calling of service providers' register methods (in reality it appears to go in the order it's set up in app/config/app.php, but hey ignore that, it's undefined behaviour so don't rely on it). As such, you don't know if your service provider has its register method called before or after Laravel's core auth service provider.

    I don't know the official way to sort this out, but the only way I can think is to do the registration in the service provider's boot method instead of its register method. You can guarantee that any given boot method is always called after all other service providers' register methods, so you will be overriding the Laravel core key, and your key won't be overridden by any normal Laravel set up. However, doing it in a boot method means that you could theoretically be too late to do what you want, if the functionality you are attempting to augment may be called in another service provider's boot method.

    Alternatively, do create yourself you own facade, use a key of your own choosing and set it all up as normal (i.e. register instance in your register method). Then replace the alias for Password with your facade. It's more boilerplate, but works more reliably.

    0 讨论(0)
  • 2021-02-10 03:21

    You should extends the Illuminate\Auth\Reminders\PasswordBroker class, not the \Illuminate\Support\Facades\Password.

    the \Illuminate\Support\Facades\Password class is a Facade, not the final class.

    You can see the final classes of the facades by:

    get_class(Password::getFacadeRoot());
    
    0 讨论(0)
提交回复
热议问题