Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

omrdev's avatar

Override a service used in vendor package

Hi Guys,

What is the best way to override a specific method in a vendor package service class?

Example:

this is the package's service provider:

public function register()
    {
        // Keycloak Web Guard
        Auth::extend('keycloak-web', function ($app, $name, array $config) {
            $provider = Auth::createUserProvider($config['provider']);
            return new KeycloakWebGuard($provider, $app->request);
        });

        // Facades
        $this->app->bind('keycloak-web', function($app) {
            return $app->make(KeycloakService::class);
        });

        // Routes
        $this->registerRoutes();

        // Middleware Group
        $this->app['router']->middlewareGroup('keycloak-web', [
            StartSession::class,
            KeycloakAuthenticated::class,
        ]);

        // Add Middleware "keycloak-web-can"
        $this->app['router']->aliasMiddleware('keycloak-web-can', KeycloakCan::class);

        // Bind for client data
        $this->app->when(KeycloakService::class)->needs(ClientInterface::class)->give(function() {
            return new Client(Config::get('keycloak-web.guzzle_options', []));
        });
    }

and this is the method that i want to override in the service : KeycloakService.php

public function getLoginUrl()
    {
        $url = $this->getOpenIdValue('authorization_endpoint');
        $params = [
            'scope' => 'openid',
            'response_type' => 'code',
            'client_id' => $this->getClientId(),
            'redirect_uri' => $this->callbackUrl,
            'state' => $this->getState(),
        ];

        return $this->buildUrl($url, $params);
    }
0 likes
2 replies
LaryAI's avatar
Level 58

One way to override a specific method in a vendor package service class is to create a new service provider in your application that extends the vendor package's service provider. In the new service provider, you can override the method by binding a new implementation of the service to the container.

Here's an example of how to do this:

  1. Create a new service provider in your application by running the following command:
php artisan make:provider MyServiceProvider
  1. In the register method of your new service provider, extend the vendor package's service provider:
use Vendor\Package\ServiceProvider as VendorServiceProvider;

class MyServiceProvider extends VendorServiceProvider
{
    // ...
}
  1. Override the method you want to change by binding a new implementation of the service to the container:
use App\Services\MyKeycloakService;

class MyServiceProvider extends VendorServiceProvider
{
    public function register()
    {
        parent::register();

        $this->app->bind(KeycloakService::class, MyKeycloakService::class);
    }
}
  1. Create a new implementation of the service that extends the vendor package's service:
use Vendor\Package\Services\KeycloakService as VendorKeycloakService;

class MyKeycloakService extends VendorKeycloakService
{
    public function getLoginUrl()
    {
        // Override the method here
    }
}
  1. Register your new service provider in the providers array of your config/app.php file:
'providers' => [
    // ...
    App\Providers\MyServiceProvider::class,
],

That's it! Now when the getLoginUrl method is called on the KeycloakService class, your implementation in MyKeycloakService will be used instead of the vendor package's implementation.

omrdev's avatar

@LaryAI

I get the following error:

Target [GuzzleHttp\ClientInterface] is not instantiable while building [App\Services\CustomKeycloakService]

because in the vendor package's service I have the following:

public function __construct(ClientInterface $client)

how can I fix this?

Please or to participate in this conversation.