PHP Access Modifiers
PHP has three visibility levels for class members. They decide who can read or call each property and method.
The three
| Keyword | Who can see it |
|---|---|
public | Anywhere — inside the class, in subclasses, in outside code. |
protected | Inside the class and its subclasses. Not from outside. |
private | Inside the declaring class only. |
Example
PHP
class BankAccount {
public string $owner;
protected float $balance;
private string $internalId;
public function __construct(string $owner, float $balance) {
$this->owner = $owner;
$this->balance = $balance;
$this->internalId = bin2hex(random_bytes(8));
}
public function balance(): float {
return $this->balance;
}
}
class SavingsAccount extends BankAccount {
public function bonus(): void {
$this->balance *= 1.01; // OK — protected visible to subclass
// $this->internalId = 'x'; // Error — private to BankAccount
}
}
$a = new BankAccount('Ada', 100);
echo $a->owner; // OK — public
// echo $a->balance; // Error — protected
// echo $a->internalId; // Error — private
Default visibility
If you omit the keyword on a property, it's public. Always be explicit.
Readonly (8.1+)
readonly stacks with visibility — useful for value objects:
PHP
class UserId {
public function __construct(public readonly int $value) {}
}
Why bother
- Hides internal state — callers depend only on your stable API.
- Lets you refactor internals without breaking callers.
- Documents intent:
privatesays "future me, don't touch this from outside".
Tip: Default to
private for properties; expose state through getters if needed. Public mutable state is the easiest way to make a class hard to change later.Example
Example
<?php
class Money {
public string $currency = 'USD';
protected int $cents;
private int $internalId;
public function __construct(int $cents) {
$this->cents = $cents;
$this->internalId = random_int(1, 1_000_000);
}
}
Try it Yourself »
Exercise
Strictest visibility.
int $internalId;
Seven letters.
Discussion
Loading…