Now let's look at a specific Eloquent Model called User
. It has some extra features on top of the regular Model.
Here's the code of the default Laravel 10 User model:
use Illuminate\Database\Eloquent\Factories\HasFactory;use Illuminate\Foundation\Auth\User as Authenticatable;use Illuminate\Notifications\Notifiable;use Laravel\Sanctum\HasApiTokens; class User extends Authenticatable{ use HasApiTokens, HasFactory, Notifiable; // ... properties like $fillable, $hidden, $casts}
Potential questions to be asked here:
Model
. What's that Authenticatable
here?use XXXXX
files? Are those PHP classes?In addition to the public app/Models/User
class, Laravel has its own "core" User class, in the Illuminate/Foundation/Auth
namespace.
So, our User Model class should extend that Illuminate User class. And we have a naming conflict!
// That would throw an errorclass User extends User{ // ...}
That's why we need to assign a different "alias" name to the extended class, on top in the "use" section, using the "as" keyword. Laravel creators called it "Authenticatable":
use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable{ // ...}
Let's look at what's inside that User
class inside the Laravel framework.
Illuminate/Foundation/Auth/User.php
use Illuminate\Auth\Authenticatable;use Illuminate\Auth\MustVerifyEmail;use Illuminate\Auth\Passwords\CanResetPassword;use Illuminate\Database\Eloquent\Model;use Illuminate\Foundation\Auth\Access\Authorizable; class User extends Model...{ use Authenticatable, Authorizable, CanResetPassword, MustVerifyEmail;}
You have already seen both syntaxes:
extends Model
means the "parent" class to inherit properties/classes from ituse Authenticatable, Authorizable, ...
are all Traits to include behavior from themBut have you noticed the hierarchy of classes here?
So yes, it is important to understand this fundamental OOP principle. You can build a "tree" of such classes, extending each other and expanding the properties/methods of each other.
Another example of this hierarchy is Laravel validation with FormRequest classes.
If you run:
php artisan make:request StoreTaskRequest
You will end up with a class something like this:
app/Http/Requests/StoreTaskRequest.php:
use Illuminate\Foundation\Http\FormRequest; class StoreTaskRequest extends FormRequest{ public function authorize() { return false; } public function rules() { return [ // ]; }}
See that extends FormRequest
? If we click it in our IDE and see what's inside, we land on this class in the Laravel framework, from the /vendor
folder:
Illuminate/Foundation/Http/FormRequest.php:
namespace Illuminate\Foundation\Http; use Illuminate\Http\Request; class FormRequest extends Request ...{ use ValidatesWhenResolvedTrait; // ...
Ok, another extends
? Let's dive deeper: what's inside of that Request
?
Illuminate/Http/Request.php:
use Symfony\Component\HttpFoundation\Request as SymfonyRequest; class Request extends SymfonyRequest{ use Concerns\CanBePrecognitive, Concerns\InteractsWithContentTypes, Concerns\InteractsWithFlashData, Concerns\InteractsWithInput, Macroable; // ...
Ok, so this Laravel class actually extends the Symfony class with the same name!
Here, we have a 3-level hierarchy, which may be even deeper if we dive into the underlying Symfony source.
So, you get the idea of hierarchy, so-called "inheritance"?
A practical non-framework example for this could be this:
TaskRequest
class with some common rulesStoreTaskRequest
and UpdateTaskRequest
, that both extend the same TaskRequest
but override/change some of its behavior in their own way.