An Overview of “Getter and Setter” Usage in Modern Object Oriented PHP
Great question — this is one of those OOP topics that sounds simple but has real architectural implications.
Since you’ve been working with PHP (and things like Kubernetes/YAML parsing recently), I’ll frame this specifically for modern PHP (8.x style).
1️⃣ What Are Getters and Setters?
In OOP, a getter reads a property.
A setter writes (modifies) a property.
Without getters/setters
class User {
public string $email;
}
$user = new User();
$user->email = "test@example.com";
echo $user->email;
Here, $email is public — anyone can change it to anything.
With getters/setters
class User {
private string $email;
public function getEmail(): string {
return $this->email;
}
public function setEmail(string $email): void {
$this->email = $email;
}
}
Now access is controlled.
2️⃣ Why Were They Created?
Originally, getters/setters were used to support:
✅ 1. Encapsulation (Core OOP principle)
You hide internal state and control access.
Instead of:
$user->email = "invalid";
You can enforce rules:
public function setEmail(string $email): void {
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException("Invalid email");
}
$this->email = $email;
}
Now the object protects itself.
✅ 2. Future-proofing
Maybe today $email is stored directly.
Tomorrow you want to:
- Normalize case
- Log changes
- Trigger an event
- Hash something
- Derive value dynamically
If you used a getter/setter, you don’t break your public API.
✅ 3. Derived values
public function getFullName(): string {
return $this->firstName . ' ' . $this->lastName;
}
No actual property — just computed logic.
3️⃣ Why Do People Say Getters/Setters Are Bad?
Because they are often misused.
🚫 The “anemic object” problem
If your class looks like this:
class User {
private string $email;
public function getEmail(): string { return $this->email; }
public function setEmail(string $email): void { $this->email = $email; }
}
Then your object is just a data container.
All logic lives elsewhere.
This is basically procedural programming disguised as OOP.
🚫 They break encapsulation if they just expose everything
If every private property has:
- a getter
- a setter
Then it’s effectively public.
You didn’t gain much.
4️⃣ Modern PHP Best Practice (PHP 8.x)
This is where things get interesting.
🧠 Best Practice Philosophy
👉 Only add a setter if it makes sense for the domain.
👉 Many objects should be immutable.
5️⃣ The Better Pattern: Constructor + No Setters
Instead of:
$user = new User();
$user->setEmail("test@example.com");
Prefer:
class User {
public function __construct(
private string $email
) {
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException();
}
}
public function getEmail(): string {
return $this->email;
}
}
Now:
- Object is valid from birth
- Cannot enter invalid state
- Safer in larger systems
- Easier to reason about
This is common in:
- Domain-Driven Design
- Event-driven systems
- Modern Laravel/Symfony apps
6️⃣ When Should You Use Setters?
Use setters when:
✅ 1. The property is truly changeable
Example:
- User can change email
- Order can change status
- Profile can update bio
But even then — prefer behavior methods:
Instead of:
$order->setStatus("shipped");
Better:
$order->markAsShipped();
That’s expressive and domain-driven.
✅ 2. You’re working with frameworks that require them
Some ORMs (like Doctrine) or serializers sometimes expect getters/setters.
But even modern frameworks support constructor-based injection now.
7️⃣ When Should You Avoid Setters?
Avoid them when:
- The value should never change (ID, creation date)
- It would allow invalid object states
- You’re just adding them “because that’s what OOP does”
8️⃣ The Real Principle Behind This
This is the deeper idea:
Objects should protect their invariants.
If a setter allows the object to become invalid, it’s a bad setter.
Example of dangerous setter:
$user->setAge(-10);
Better:
public function celebrateBirthday(): void {
$this->age++;
}
That enforces real-world logic.
9️⃣ The Modern PHP Summary
❌ Old-school approach
- Private properties
- Getter + setter for everything
✅ Modern approach
- Constructor injection
- Immutable objects where possible
- Behavior-driven methods
- Minimal setters
- Protect invariants
10️⃣ Simple Rule of Thumb
Ask yourself:
“Does this object need to allow this value to change?”
If yes → maybe a setter
If no → constructor only
If it’s business behavior → use a method like approve(), publish(), cancel()
If you’d like, I can:
- Show you a “bad OOP PHP example”
- Then refactor it into a clean modern design
- Or relate it to something like a Kubernetes config object (since you were looking at that recently)
Which would help more?
Recent content
-
4 hours 53 minutes ago
-
8 hours 53 minutes ago
-
1 day 1 hour ago
-
4 days 10 hours ago
-
1 week 1 day ago
-
1 week 3 days ago
-
1 week 3 days ago
-
1 week 3 days ago
-
1 week 3 days ago
-
2 weeks 4 days ago