Skip to content
intermediate Phase 8 · SOLID & Design Principles

SOLID & Design Principles - OOP Fundamentals

The four pillars of Object-Oriented Programming in PHP: encapsulation, abstraction, inheritance, and polymorphism with real-world Magento examples

45m
0 problems
Topic Progress 0%

Encapsulation: Controlling Access to State

What is Encapsulation?

Encapsulation is the bundling of data (properties) and methods that operate on that data into a single unit (class), while restricting direct access to some components. This protects object integrity by preventing external code from putting the object into an invalid state.

Access Modifiers in PHP

PHP provides three access modifiers:

Modifier Class Child Class Outside
public Yes Yes Yes
protected Yes Yes No
private Yes No No

Example: Encapsulated Product Price

namespace Vendor\Catalog\Model;

class PriceManager
{
    private float $basePrice;
    private float $taxRate;
    private float $discountPercent = 0;

    public function __construct(float $basePrice, float $taxRate)
    {
        $this->setBasePrice($basePrice);
        $this->taxRate = $taxRate;
    }

    private function setBasePrice(float $price): void
    {
        if ($price < 0) {
            throw new \InvalidArgumentException('Price cannot be negative');
        }
        $this->basePrice = $price;
    }

    public function applyDiscount(float $percent): void
    {
        if ($percent < 0 || $percent > 100) {
            throw new \InvalidArgumentException('Discount must be 0-100');
        }
        $this->discountPercent = $percent;
    }

    public function getFinalPrice(): float
    {
        $discounted = $this->basePrice * (1 - $this->discountPercent / 100);
        return $discounted * (1 + $this->taxRate);
    }

    public function getBasePrice(): float
    {
        return $this->basePrice;
    }
}

Why This Matters

Without encapsulation, external code could set $basePrice = -100 and break calculations. The validated setter prevents invalid states. In Magento, nearly every model uses encapsulation — look at Magento\Catalog\Model\Product which has private/protected properties with controlled access via getters and setters.

Magento Example: Product Entity

// Magento\Catalog\Model\Product (simplified)
class Product extends \Magento\Framework\Model\AbstractModel
{
    protected $sku;
    protected $name;
    protected $price;

    public function getSku(): ?string
    {
        return $this->getData('sku');
    }

    public function setSku(string $sku): ProductInterface
    {
        return $this->setData('sku', $sku);
    }
}

The setData method provides a controlled way to modify internal state, maintaining encapsulation even with the generic data array pattern.

Quiz

1. Which access modifier allows access only within the defining class and its children?

Question 1 options

2. What problem does encapsulation prevent?

Question 2 options

3. In Magento, why are Product properties accessed via getter/setter methods instead of public properties?

Question 3 options

Flashcards

Question

What are the three PHP access modifiers?

Answer

public (everywhere), protected (class + children), private (class only)

Question

What is encapsulation?

Answer

Bundling data and methods while restricting direct access to protect object integrity

Question

Why does Magento use getters/setters instead of public properties?

Answer

To maintain encapsulation, support magic methods, and enable the getData/setData data array pattern

Revision Notes

Key Takeaways

  • 1. Encapsulation bundles data + methods and controls access via public/protected/private
  • 2. Private properties with public getters/setters enforce validation rules
  • 3. Magento models extensively use encapsulation through getData/setData pattern
  • 4. Proper encapsulation makes code easier to test and refactor

Interview Tips

  • Be ready to explain why a property might be private vs protected
  • Know how Magento's magic __call and getData/setData relate to encapsulation
  • Discuss trade-offs: too much encapsulation can create boilerplate

Cheat Sheet

public    → accessible everywhere
protected → class + children only
private   → defining class only

Magento pattern:
  private $data = [];
  public function getData($key) { return $this->data[$key]; }
  public function setData($key, $val) { $this->data[$key] = $val; return $this; }