Public, Private, Protected в PHP: гид по инкапсуляции

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

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.

Блоги

Рекомендаций по книгам