Understanding protected, $fillable, and #[Fillable] in Laravel
If you’re learning Laravel, you may have noticed something unusual in newer Laravel models:
#[Fillable(['name', 'email', 'password'])]
#[Hidden(['password', 'remember_token'])]
class User extends Authenticatable
{
//
}If you’ve learned the traditional Laravel approach, you might be wondering:
What happened to
protected $fillableandprotected $hidden?
And more importantly:
Is
#[Fillable]a property? Can I make itprotected?
To understand this properly, we need to separate three PHP concepts:
- Properties
- Visibility
- Attributes
Let’s start from the beginning.
1. What is a Property in PHP?
A property is essentially a variable that belongs to a class or object.
For example:
class User
{
public $name;
public $email;
}Here, $name and $email are properties of the User class.
We can create an object:
$user = new User();
$user->name = "Aditya";
$user->email = "aditya@example.com";Now the object contains data:
User object
│
├── name → "Aditya"
└── email → "aditya@example.com"So when you see:
$user->namename is a property belonging to the $user object.
2. Properties Can Have Visibility
PHP allows us to control who can access a property.
There are three main visibility modifiers:
public
protected
privateFor example:
class User
{
public $name;
protected $email;
private $password;
}These three properties have different access rules.
public
A public property can be accessed from anywhere.
$user = new User();
$user->name = "Aditya";
echo $user->name;This works because $name is public.
protected
A protected property can be accessed inside the class and by child classes.
class User
{
protected $email;
}You cannot normally access it directly from outside:
$user = new User();
$user->email = "aditya@example.com";This will result in an access error because $email is protected.
private
A private property can only be accessed from within the class that declared it.
class User
{
private $password;
}Outside the class:
$user->password = "secret";is not allowed.
3. What Does protected $fillable Mean?
Now let’s look at Laravel.
A traditional Laravel User model might contain:
class User extends Authenticatable
{
protected $fillable = [
'name',
'email',
'password',
];
}Let’s break this apart.
protectedis the visibility modifier.
$fillableis the property name.
[
'name',
'email',
'password'
]is the value stored in that property.
So:
protected $fillable = [
'name',
'email',
'password',
];means:
Create a protected property called
$fillablecontaining these three values.
4. Why Does Laravel Need $fillable?
Laravel uses $fillable to control mass assignment.
For example:
$user = User::create([
'name' => 'Aditya',
'email' => 'aditya@example.com',
'password' => 'secret',
]);Laravel needs to know which fields are allowed to be assigned this way.
That’s where $fillable comes in:
protected $fillable = [
'name',
'email',
'password',
];It tells Laravel:
These attributes are allowed for mass assignment.
This is an important security mechanism because you don’t want users to arbitrarily assign sensitive database fields.
5. So What Is #[Fillable(...)]?
Now we come to the newer syntax:
#[Fillable(['name', 'email', 'password'])]This looks similar to $fillable, but it is fundamentally different.
It is not a property.
It is a PHP Attribute.
PHP introduced Attributes in PHP 8.
The #[] syntax identifies an Attribute:
#[SomeAttribute]You can think of an Attribute as metadata or additional instructions attached to PHP code.
For example:
#[Fillable(['name', 'email', 'password'])]
class User extends Authenticatable
{
}The Fillable attribute is attached to the User class.
Laravel can then read that information and use it to configure the model.
6. Why Can’t We Write protected #[Fillable(...)]?
This is where the difference becomes important.
You might think:
protected #[Fillable(...)]But this is not how PHP Attributes work.
Why?
Because:
protected $fillable;is a property declaration.
While:
#[Fillable(...)]is an attribute.
They are different language constructs.
Think of it like this:
protected $fillable
│ │
│ └── Property
│
└── VisibilityWhereas:
#[Fillable(...)]
│
└── Attribute / MetadataThere is no protected attached to the Attribute itself.
7. You Can Put Attributes on Properties
Here’s where it gets interesting.
PHP Attributes can actually be attached to different things, including properties.
For example:
class User
{
#[SomeAttribute]
public string $name;
}Here:
public string $name;is still the property.
And:
#[SomeAttribute]is metadata attached to that property.
So the concepts can exist together:
class User
{
#[SomeAttribute]
protected string $name;
}Here:
protected→ visibility$name→ propertystring→ property type#[SomeAttribute]→ attribute
8. A Simple Mental Model
Imagine a car.
The properties describe what the car has:
class Car
{
public string $color;
protected int $speed;
}The car has:
color
speedThose are properties.
The visibility tells us who can access them:
public → everyone
protected → class + children
private → class onlyNow imagine putting a label on the car:
#[Electric]
class Car
{
}#[Electric] isn't a property such as $color.
It’s metadata telling PHP or a framework something about the class.
9. Traditional Laravel vs Attribute-Based Laravel
Traditional Laravel:
class User extends Authenticatable
{
protected $fillable = [
'name',
'email',
'password',
]; protected $hidden = [
'password',
'remember_token',
];
}Here we have two properties:
$fillable
$hiddenBoth are protected.
With the attribute approach:
#[Fillable(['name', 'email', 'password'])]
#[Hidden(['password', 'remember_token'])]
class User extends Authenticatable
{
}Now we don’t have $fillable and $hidden properties written in the class.
Instead, we’re attaching Laravel attributes to the class.
10. Don’t Confuse $fillable With Fillable
This tiny difference is extremely important.
$fillable
protected $fillable = [
'name',
'email',
];$fillable is a property.
Fillable
#[Fillable([
'name',
'email',
])]Fillable is an Attribute class.
Notice the difference:
$fillable
↑
Propertyversus:
Fillable
↑
AttributeThe $ is a useful clue that you're dealing with a variable/property.
11. What About Methods?
The same concept applies to methods.
A method is an action:
class User
{
public function login()
{
// ...
}
}You can also attach an Attribute to a method:
class User
{
#[SomeAttribute]
public function login()
{
// ...
}
}Here:
publiccontrols visibility.
login()is the method.
#[SomeAttribute]is metadata attached to the method.
Again, these are separate concepts.
12. The Three Things You Should Remember
When reading PHP/Laravel code, mentally separate these:
Property
protected $fillable;A property stores data belonging to an object.
Visibility
public
protected
privateVisibility controls who can access a property or method.
Attribute
#[Fillable(...)]An Attribute provides metadata/instructions that PHP or a framework can read.
13. Final Example
Let’s put everything together:
#[Fillable(['name', 'email', 'password'])]
#[Hidden(['password', 'remember_token'])]
class User extends Authenticatable
{
protected string $email;
private string $password;
public function login()
{
// Login logic
}
}Now identify each part:
#[Fillable(...)]
↓
Attribute
#[Hidden(...)]
↓
Attribute
protected string $email
│ │ │
│ │ └── Property
│ └────────── Type
└──────────────────── Visibility
private string $password
│ │ │
│ │ └── Property
│ └────────── Type
└────────────────── Visibility
public function login()
│ │
│ └── Method
└───────── VisibilityOnce you understand this distinction, Laravel’s newer syntax becomes much less confusing.
The Golden Rule
Whenever you see:
public
protected
privatethink:
Who is allowed to access this?
Whenever you see:
$somethinginside a class, think:
This is probably a property.
Whenever you see:
#[Something(...)]think:
This is an Attribute — metadata/instructions attached to PHP code.
These three concepts are related, but they are not interchangeable.
Understanding this distinction is one of those small PHP concepts that makes reading modern Laravel code dramatically easier.
Комментарии (0)
Пока нет комментариев — будьте первым.