An Overview of “Getter and Setter” Usage in Modern Object Oriented PHP

Submitted by admin on

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
Drupal Topics