Public, Private, Protected в PHP: почему без них ваш код — хаос?
Представьте, что вы строите дом. У вас есть входная дверь (все могут войти), спальня с замком (только для семьи) и сейф в стене (доступ есть только у вас). В мире объектно-ориентированного программирования (ООП) на PHP такие «двери» и «замки» называются модификаторами доступа.
Если вы хоть раз писали классы на PHP, вы натыкались на слова public, private и protected. Но что они означают на самом деле? Почему нельзя всё сделать public и жить спокойно? Ответ прост: без них ваш код превратится в проходной двор, где любой скрипт может случайно сломать логику программы.
В этой статье мы разберёмся с модификаторами доступа в PHP на реальных примерах, поймём разницу между ними и научимся применять их для создания надёжного, гибкого кода. Это руководство создано на основе популярного вопроса со Stack Overflow и адаптировано для образовательного сайта pythonlib.ru.
Что такое модификаторы доступа и зачем они нужны?
Модификаторы доступа — это ключевые слова, которые определяют, откуда можно обращаться к свойствам и методам класса. Они — основа инкапсуляции (одного из четырёх столпов ООП). Инкапсуляция прячет внутреннее устройство объекта и защищает данные от некорректного использования.
В PHP есть три уровня доступа:
- Public — доступно всем (и внутри класса, и снаружи).
- Private — доступно только внутри самого класса.
- Protected — доступно внутри класса и в классах-наследниках.
Давайте разберём каждый на практических примерах.
Public: «Вход без стука»
Модификатор public — самый открытый. Свойства и методы, объявленные как public, можно читать и изменять откуда угодно: из другого класса, из глобального скрипта, из космоса (шутка).
<?php
class Car {
public $brand = 'Toyota';
public function honk() {
return 'Beep!';
}
}
$myCar = new Car();
echo $myCar->brand; // Toyota — работает
$myCar->brand = 'Honda'; // Меняем — работает
echo $myCar->honk(); // Beep!
?>
Вроде бы удобно? Но есть проблема. Представьте, что в классе User есть свойство public $password. Любой код снаружи может его прочитать и изменить. Это катастрофа для безопасности.
Когда использовать: для методов, которые являются частью публичного API класса (например, getUserName()), или для констант.
Private: «Сейф, который не взломать»
Модификатор private — полная противоположность public. Свойство или метод доступны только внутри того класса, где они объявлены. Даже классы-наследники не видят private-члены родителя.
<?php
class BankAccount {
private $balance = 1000;
private function calculateInterest() {
return $this->balance * 0.05;
}
public function getBalance() {
return $this->balance;
}
public function applyInterest() {
$this->balance += $this->calculateInterest();
}
}
$account = new BankAccount();
// echo $account->balance; // Ошибка! Cannot access private property
// echo $account->calculateInterest(); // Ошибка! Cannot access private method
echo $account->getBalance(); // 1000 — работает, потому что метод public
$account->applyInterest();
echo $account->getBalance(); // 1050
?>
В этом примере $balance и calculateInterest() скрыты от внешнего мира. Мы управляем балансом только через публичные методы getBalance() и applyInterest(). Это и есть инкапсуляция: мы контролируем, как изменяются данные.
Важно: private-методы нельзя переопределить в дочернем классе. Они полностью изолированы.
Protected: «Семейный доступ»
Модификатор protected — золотая середина. Он работает как private, но с одним важным отличием: дочерние классы (наследники) могут обращаться к protected-членам. Внешний код по-прежнему не имеет доступа.
<?php
class Animal {
protected $name = 'Unknown';
protected function makeSound() {
return 'Some sound';
}
public function getName() {
return $this->name;
}
}
class Dog extends Animal {
public function setName($name) {
$this->name = $name; // Доступно, так как protected
}
public function getDogSound() {
return $this->makeSound(); // Доступно, так как protected
}
// Можно переопределить protected метод
protected function makeSound() {
return 'Woof!';
}
}
$dog = new Dog();
$dog->setName('Rex');
echo $dog->getName(); // Rex
// echo $dog->name; // Ошибка! Protected — снаружи нельзя
echo $dog->getDogSound(); // Woof! (переопределённый метод)
?>
Когда использовать protected: когда вы пишете библиотеку или фреймворк и хотите, чтобы разработчики могли расширять ваш класс, но не имели доступа к внутренним данным напрямую.
Сравнительная таблица: Public vs Private vs Protected
Чтобы закрепить, вот наглядное сравнение:
| Модификатор | Внутри класса | В наследнике | Снаружи (глобально) |
|---|---|---|---|
public |
✅ Да | ✅ Да | ✅ Да |
protected |
✅ Да | ✅ Да | ❌ Нет |
private |
✅ Да | ❌ Нет | ❌ Нет |
Типичные ошибки новичков (и как их избежать)
Вот несколько граблей, на которые наступают почти все, кто изучает модификаторы доступа в PHP:
- Ошибка: «Всё public» — кажется, что так проще. Но когда проект разрастается, вы не можете уследить, кто и как меняет ваши данные. Используйте private по умолчанию, а public — только для API.
- Ошибка: «Protected — это почти private» — нет. Protected создан для наследования. Если вы не планируете наследование, используйте private.