PHP Access Modifiers
Access modifiers control the visibility of class properties and methods — determining where in a program they can be accessed or called. PHP has three access modifiers: public, protected, and private. Choosing the correct modifier for each property and method is a fundamental part of designing well-structured, secure classes.
public
A public property or method can be accessed from anywhere: inside the class, in any child class, or from outside the class entirely. This is the default behavior if no modifier is specified.
<?php
class BankAccount {
public $accountNumber;
public $holderName;
public function displayInfo() {
echo "Account: " . $this->accountNumber . " - " . $this->holderName;
}
}
$account = new BankAccount();
$account->accountNumber = "ACC-001"; // Accessible from outside the class
$account->holderName = "Alice";
$account->displayInfo();
?>
private
A private property or method can only be accessed from within the class where it is defined. It is completely hidden from outside code and from child classes. Private access is the strictest level of visibility.
<?php
class BankAccount {
private $balance;
private $pin;
public function __construct($initialBalance, $pin) {
$this->balance = $initialBalance;
$this->pin = $pin;
}
public function deposit($amount) {
if ($amount > 0) {
$this->balance += $amount;
echo "Deposited: $" . $amount;
}
}
public function withdraw($amount, $pin) {
if ($pin !== $this->pin) {
echo "Incorrect PIN.";
return;
}
if ($amount > $this->balance) {
echo "Insufficient funds.";
return;
}
$this->balance -= $amount;
echo "Withdrew: $" . $amount;
}
public function getBalance() {
return $this->balance; // Controlled access to private data
}
}
$acc = new BankAccount(1000, "1234");
$acc->deposit(500);
$acc->withdraw(200, "1234");
echo $acc->getBalance(); // 1300
// $acc->balance = 9999; // Fatal error - cannot access private property
// $acc->pin = "0000"; // Fatal error - cannot access private property
?>
Making the balance and PIN private ensures that outside code cannot change these values directly — they must go through the controlled methods the class provides.
protected
A protected property or method can be accessed within the class where it is defined and within any child class that extends it. It cannot be accessed from outside the class hierarchy.
<?php
class Vehicle {
protected $speed = 0;
protected $maxSpeed;
public function __construct($maxSpeed) {
$this->maxSpeed = $maxSpeed;
}
protected function validateSpeed($speed) {
return min($speed, $this->maxSpeed);
}
}
class Car extends Vehicle {
public function accelerate($amount) {
$newSpeed = $this->speed + $amount;
$this->speed = $this->validateSpeed($newSpeed); // Accessible in child class
echo "Speed: " . $this->speed . " km/h";
}
}
$car = new Car(200);
$car->accelerate(150); // Speed: 150 km/h
$car->accelerate(100); // Speed: 200 km/h (capped at maxSpeed)
// $car->speed; // Fatal error - protected
// $car->validateSpeed(50); // Fatal error - protected method
?>
Access Modifier Summary
| Modifier | Same Class | Child Class | Outside Class |
|---|---|---|---|
public | Yes | Yes | Yes |
protected | Yes | Yes | No |
private | Yes | No | No |
Getters and Setters
When properties are private or protected, external code needs a controlled way to read or modify them. Getter and setter methods provide this access while allowing validation or logic to run during access.
<?php
class Product {
private string $name;
private float $price;
public function __construct(string $name, float $price) {
$this->setName($name);
$this->setPrice($price);
}
// Getter
public function getName(): string {
return $this->name;
}
// Setter with validation
public function setName(string $name): void {
if (strlen(trim($name)) < 2) {
throw new InvalidArgumentException("Name must be at least 2 characters.");
}
$this->name = trim($name);
}
// Getter
public function getPrice(): float {
return $this->price;
}
// Setter with validation
public function setPrice(float $price): void {
if ($price < 0) {
throw new InvalidArgumentException("Price cannot be negative.");
}
$this->price = $price;
}
}
$product = new Product("Laptop", 999.99);
echo $product->getName(); // Laptop
echo $product->getPrice(); // 999.99
$product->setPrice(849.99);
echo $product->getPrice(); // 849.99
// $product->setPrice(-10); // Throws InvalidArgumentException
?>
Magic Methods __get and __set
PHP's __get() and __set() magic methods intercept attempts to access or modify inaccessible properties. They provide a flexible alternative to writing individual getter/setter methods for every property.
<?php
class Config {
private array $data = [];
public function __set(string $name, $value): void {
$this->data[$name] = $value;
}
public function __get(string $name) {
return $this->data[$name] ?? null;
}
public function __isset(string $name): bool {
return isset($this->data[$name]);
}
}
$config = new Config();
$config->theme = "dark";
$config->language = "en";
echo $config->theme; // dark
echo $config->language; // en
var_dump(isset($config->theme)); // bool(true)
?>
Key Points
publicmembers are accessible everywhere — inside the class, in child classes, and from outside code.privatemembers are accessible only within the class where they are defined.protectedmembers are accessible within the defining class and any class that inherits from it.- Use
privateby default for properties, exposing them through getter and setter methods when needed. - Getters and setters allow controlled access to private data, including validation logic.
- The
__get()and__set()magic methods intercept access to inaccessible properties dynamically.
