sheng
sheng

Reputation: 1372

Laravel Eloquent - accessing parent model from child model returns child model

Extending Eloquent models seems to be a thing people do. I have an interesting issue:

FooBase.php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class FooBase extends Model {
     protected $table = 'foo_bar';
}

FooExtends.php

namespace App\Models;

class FooExtends extends FooBase {
     public function method() {
           return FooBase::first(); // or even parent::first()
     }
}

Calling (new FooExtends())->method() returns an instance of FooExtends instead of FooBase. (Just static methods affected, which may answer my own question, but one would think Laravel would handle this. Calling (new FooBase())->first() from within the child class works.) What's going on here?

PHP 7.3, Laravel 5.7

Upvotes: 4

Views: 1363

Answers (1)

Aken Roberts
Aken Roberts

Reputation: 13467

This is a really interesting PHP quirk that doesn't apply static context when calling an ancestor class.

Basically, the "static" call to FooBase::first() gets interpreted the same as parent::first(), because PHP knows that FooBase is the parent of the current class context FooExtends. And since calls to parent stay within the context of the current object, the first() call ends up being routed to __call() and not __callStatic() (which would create a new context using the FooBase class).

Really interesting thing to learn about PHP internals and class contexts. Thanks for giving me a reason to poke around. :)

Upvotes: 2

Related Questions