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

petersowah's avatar

What's the best way to override a service provider class in a vendor file?

I need to load my custom class in place of the vendor implementation. For context, I have an integration with OneSignal which works by sending notifications to one client. I'm trying to override the Service Provider implementation by the package so I can send notifications to multiple clients by specifying which keys to use when sending a notification. Thank you in advance.

0 likes
7 replies
LaryAI's avatar
Level 58

To override a service provider class in a vendor file, you can follow these steps:

  1. Create Your Custom Service Provider: First, create your custom service provider class that extends the original service provider. This allows you to override or extend the functionality as needed.

    namespace App\Providers;
    
    use Vendor\Package\OriginalServiceProvider;
    
    class CustomServiceProvider extends OriginalServiceProvider
    {
        public function register()
        {
            // Your custom registration logic
        }
    
        public function boot()
        {
            // Your custom boot logic
        }
    }
    
  2. Register Your Custom Service Provider: Next, you need to register your custom service provider in the config/app.php file. Make sure to remove or comment out the original service provider to avoid conflicts.

    'providers' => [
        // Other service providers...
    
        // Comment out the original service provider
        // Vendor\Package\OriginalServiceProvider::class,
    
        // Add your custom service provider
        App\Providers\CustomServiceProvider::class,
    ],
    
  3. Override Bindings (if necessary): If the original service provider binds certain classes or interfaces in the service container, you may need to override these bindings in your custom service provider.

    namespace App\Providers;
    
    use Vendor\Package\OriginalServiceProvider;
    use Illuminate\Support\ServiceProvider;
    
    class CustomServiceProvider extends ServiceProvider
    {
        public function register()
        {
            // Override bindings here
            $this->app->bind('OriginalClass', 'App\CustomClass');
        }
    
        public function boot()
        {
            // Custom boot logic
        }
    }
    
  4. Custom Implementation: Implement your custom logic in the overridden methods or in new methods within your custom service provider.

    namespace App;
    
    class CustomClass
    {
        public function sendNotification($clients, $message)
        {
            foreach ($clients as $client) {
                // Custom logic to send notification to multiple clients
            }
        }
    }
    

By following these steps, you can effectively override a service provider class in a vendor file and implement your custom logic. This approach ensures that your changes are maintainable and do not directly modify the vendor files, which can be overwritten during updates.

martinbean's avatar

I'm trying to override the Service Provider implementation by the package so I can send notifications to multiple clients by specifying which keys to use when sending a notification.

@petersowah This sounds like you just need to create a custom notification channel, not something you’d need to actually override any service providers for.

1 like
petersowah's avatar

@martinbean For additional context, I'm using OneSignal for push notifications in my API. I have two client apps, one for users and the other for travel agencies. To create an agency, you need a user account which is linked to the agency in the database. The notifications use the users table, meaning both Onesignal configs use the same table. What I'm trying to achieve is to be able to set the app keys on the fly when sending notifications. The onesignal client is configured in the vendor service provider and that implementation is what I need to override.

Snapey's avatar
Snapey
Best Answer
Level 122

@petersowah your own notifications service provider can be the one to send, and within it, you can defer to oneSignal once you have done what you need to do.

1 like
petersowah's avatar

@Snapey How do I make my application use my service provider implementation when it's configuring the client instead of the service provider from the package? Sorry, but I'm a bit confused in achieving this. Thanks in advance.

This is the config I have;

'onesignal' => [
        'agency' => [
            'app_id' => env('ONESIGNAL_AGENCY_APP_ID'),
            'rest_api_key' => env('ONESIGNAL_AGENCY_REST_API_KEY'),
            'guzzle_client_timeout' => env('ONESIGNAL_GUZZLE_CLIENT_TIMEOUT', 0),
        ],

        'traveler' => [
            'app_id' => env('ONESIGNAL_TRAVELER_APP_ID'),
            'rest_api_key' => env('ONESIGNAL_TRAVELER_REST_API_KEY'),
            'guzzle_client_timeout' => env('ONESIGNAL_GUZZLE_CLIENT_TIMEOUT', 0),
        ],
    ],

This is the error, I'm currently getting:

php local.ERROR: Undefined array key "app_id" {"exception":"[object] (ErrorException(code: 0): Undefined array key \"app_id\" at .../vendor/berkayk/onesignal-laravel/src/OneSignalServiceProvider.php:39)

and the vendor service provider configuring the client;

<?php

namespace Berkayk\OneSignal;

use Illuminate\Support\ServiceProvider;

class OneSignalServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        $configPath = __DIR__ . '/../config/onesignal.php';

        $this->publishes([$configPath => config_path('onesignal.php')], 'config');
        $this->mergeConfigFrom($configPath, 'onesignal');

        if ($this->app instanceof Laravel\Lumen\Application) {
            $this->app->configure('onesignal');
        }
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton('onesignal', function ($app) {
            $config = isset($app['config']['services']['onesignal']) ? $app['config']['services']['onesignal'] : null;
            if (is_null($config)) {
                $config = $app['config']['onesignal'] ?: $app['config']['onesignal::config'];
            }

            return new OneSignalClient($config['app_id'], $config['rest_api_key'], $config['user_auth_key'] , $config['guzzle_client_timeout']);
        });

        $this->app->alias('onesignal', 'Berkayk\OneSignal\OneSignalClient');
    }

    public function provides() {
        return ['onesignal'];
    }
}```
puklipo's avatar

Write which package you are using.

Please or to participate in this conversation.