PHP Access Modifiers

Access modifiers control which parts of your code are allowed to read or change a property or call a method, forming the basis of encapsulation.

Why control access?

One of the main benefits of OOP is being able to protect an object's internal data from the rest of the program. Access modifiers are keywords you place before a property or method to decide who can use it. This lets a class expose a safe, deliberate interface while keeping its inner workings hidden, which is the idea called encapsulation.

ModifierAccessible from
publicAnywhere: inside the class, in child classes, and from outside
protectedInside the class and in classes that extend it
privateOnly inside the class that declares it

public, protected, and private

A public member can be reached from anywhere and is the default when you write a method with no modifier. A protected member is visible inside the class and any subclass but not from outside. A private member is locked to the single class that declares it, so not even a child class can touch it directly.

Comparing the three modifiers

<?php
class Account
{
    public string $owner;      // open to everyone
    protected string $bankId;  // this class and subclasses
    private float $balance = 0; // this class only

    public function __construct(string $owner)
    {
        $this->owner = $owner;
    }

    public function deposit(float $amount): void
    {
        $this->balance += $amount; // allowed: same class
    }

    public function getBalance(): float
    {
        return $this->balance;
    }
}

$acc = new Account("Sam");
$acc->deposit(100);
echo $acc->getBalance(); // 100
// echo $acc->balance;   // Error: balance is private
?>

In the example above, the balance can only be changed through the deposit method, so no outside code can set it to a nonsense value directly. This is encapsulation in action: the class keeps full control over how its most important data is modified.

Getters and setters

A common pattern is to make a property private and provide public methods to read it (a getter) and to change it (a setter). The setter can validate the new value before storing it, guaranteeing the property stays correct no matter who calls it.

A validating setter

<?php
class Person
{
    private int $age = 0;

    public function setAge(int $age): void
    {
        if ($age < 0 || $age > 150) {
            throw new InvalidArgumentException("Age out of range.");
        }
        $this->age = $age;
    }

    public function getAge(): int
    {
        return $this->age;
    }
}

$p = new Person();
$p->setAge(30);
echo $p->getAge(); // 30
?>
  • Start with the most restrictive access that still works, usually private.
  • Open a member up to protected or public only when something truly needs it.
  • Expose behavior through public methods rather than exposing raw data.
  • Use setters to validate incoming values before they are stored.
Note: Keeping properties private by default makes your classes easier to change later. Because outside code only depends on your public methods, you can rework the internals freely without breaking anything that uses the class.