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

Yorki's avatar
Level 11

Override existing class by binding

Hello,

I'm thinking of a way to implement plugin system in my project. What I want to accomplish is being able to customize eloquent model for example. Let's say I have plugin called UserRoles and I want to add customRoles method to my user model without actual modification of source code.

My first thought was to bind:

$this->app->bind(\App\User::class, CustomUser::class);

However everytime I'd like to use my User class I'd have to get it from container since this won't work:

use App\User;

...

$user = new User;
$user->customRoles();

while this will work:

use App\User;

...

$user = app(User::class);
$user->customRoles();

Is there better approach of doing this? I'd have to take care of existing code like AuthController too.

0 likes
3 replies
NickVahalik's avatar

The User model is part of your app. Why wouldn't you just edit it?

Alternatively, perhaps a Macro would work instead?

Cronix's avatar

You might need to specify the user model to use in the /config/auth.php config file.

The default is

'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\User::class,
        ],

        // 'users' => [
        //     'driver' => 'database',
        //     'table' => 'users',
        // ],
    ],

But I agree with @NickVahalik Just edit the existing User class itself. It's not a vendor file and is meant to be changed to how you need.

Yorki's avatar
Level 11

User model is just an example. I will have base application which I want to make customizable by plugins without touching core files. Another idea crossed my mind:

class ExtendableModel extends Model
{
    /**
     * @var array
     */
    protected static $extendedFillable = [];

    /**
     * @return array
     */
    public function getFillable()
    {
        return array_merge($this->fillable, self::$extendedFillable);
    }

    /**
     * @param string $fieldName
     *
     * @return $this
     */
    public function addFillable($fieldName)
    {
        if (in_array($fieldName, self::$extendedFillable)) {
            return $this;
        }

        self::$extendedFillable[] = $fieldName;

        return $this;
    }
}
class User extends ExtendableModel

Then I could bootstrap my extension with

app(\App\User::class)
    ->addFillable('role');

This allows me to add some fillable field, but I could use this idea to add closures too.

Please or to participate in this conversation.