private
Ключевое слово private в PHP объявляет член класса приватным — доступным только внутри самого класса. Подробное руководство с примерами.
Ключевое слово private в PHP
private — это модификатор видимости (также называемый модификатором доступа). Когда свойство или метод помечено как private, оно может быть прочитано и вызвано только изнутри того же класса — ни снаружи объекта, ни из дочернего класса, расширяющего его.
Видимость — основа инкапсуляции: она позволяет классу скрывать внутренние данные и вспомогательную логику за контролируемым публичным интерфейсом, чтобы внешний мир зависел только от того, что вы решили открыть. В PHP есть три уровня видимости:
| Модификатор | Тот же класс | Дочерний класс | Снаружи класса |
|---|---|---|---|
public | да | да | да |
protected | да | да | нет |
private | да | нет | нет |
На этой странице рассматривается синтаксис private, когда и зачем его использовать, а также распространённые подводные камни — наследование, правило «тот же класс, другой объект» и поведение при ошибках. Для общей картины см. Модификаторы доступа PHP и Классы и объекты PHP.
Синтаксис
Добавьте ключевое слово private перед объявлением свойства или метода:
class MyClass {
private $myPrivateVariable;
private function myPrivateFunction() {
// Only code inside MyClass can call this.
}
}Приватный член полностью доступен внутри класса — другие методы MyClass могут читать $this->myPrivateVariable и вызывать $this->myPrivateFunction() — но любой доступ снаружи вызывает Error.
Примеры
Рассмотрим несколько практических примеров использования ключевого слова private:
Примеры PHP private
<?php
// Example 1
class Person
{
private $name;
public function __construct($name)
{
$this->name = $name;
}
private function getName()
{
return $this->name;
}
public function greet()
{
$name = $this->getName();
echo "Hello, $name!" . PHP_EOL;
}
}
$person = new Person("John");
$person->greet(); // Output: Hello, John!
// Example 2
class BankAccount
{
private $balance = 0;
public function deposit($amount)
{
$this->balance += $amount;
}
public function withdraw($amount)
{
if ($amount > $this->balance) {
echo "Insufficient funds!" . PHP_EOL;
} else {
$this->balance -= $amount;
echo "Withdrawal successful!" . PHP_EOL;
}
}
}
$account = new BankAccount();
$account->deposit(100);
$account->withdraw(50); // Output: Withdrawal successful!
$account->withdraw(100); // Output: Insufficient funds!В обоих примерах $name, getName() и $balance являются частью внутреннего механизма класса. Внешний мир работает только с greet(), deposit() и withdraw() — безопасными, валидируемыми точками входа. Это инкапсуляция в действии: баланс BankAccount никогда не может стать отрицательным, поскольку ничто снаружи класса не может записать его напрямую.
Что происходит при нарушении правила
Обращение к приватному члену снаружи класса вызывает фатальный Error, а не тихий null:
<?php
class Person
{
private $name = "John";
}
$p = new Person();
echo $p->name;
// PHP Fatal error: Uncaught Error: Cannot access private property Person::$nameЭто сделано намеренно — ошибка сразу обнаруживается, а не даёт коду молча зависеть от внутренних деталей.
Private — на уровне класса, а не объекта
Распространённый сюрприз: приватные члены видны между двумя экземплярами одного класса. Граница «private» — это класс, поэтому один объект может читать приватные поля другого объекта, если оба имеют одинаковый тип:
<?php
class Money
{
private $cents;
public function __construct($cents)
{
$this->cents = $cents;
}
// Reads $other->cents directly — allowed, same class.
public function add(Money $other)
{
return new Money($this->cents + $other->cents);
}
public function format()
{
return number_format($this->cents / 100, 2);
}
}
$total = (new Money(150))->add(new Money(350));
echo $total->format(); // Output: 5.00Private и наследование
В отличие от protected, приватный член не наследуется подклассами. Дочерний класс не видит приватные члены родителя, и если он объявляет член с тем же именем, он получает собственную отдельную копию:
<?php
class Base
{
private $value = "base";
public function show()
{
echo $this->value . PHP_EOL;
}
}
class Child extends Base
{
private $value = "child";
}
(new Child())->show(); // Output: baseshow() был определён в Base, поэтому он видит собственное приватное $value класса Base — $value дочернего класса является совершенно отдельным свойством. Если вы хотите, чтобы подклассы разделяли и переопределяли член, используйте вместо этого protected. Подробнее см. в Наследование PHP.
Когда использовать private
- Внутреннее состояние, которое должно оставаться валидным — например, баланс
BankAccountвыше. Предоставляйте мутаторы (deposit,withdraw), которые обеспечивают соблюдение правил. - Вспомогательные методы, являющиеся деталями реализации, чтобы вы могли переименовывать или переписывать их, не нарушая вызывающий код.
- По умолчанию выбирайте наиболее ограничительный уровень. Начинайте с
private; расширяйте доprotectedилиpublicтолько при реальной необходимости. Ослабить видимость гораздо проще, чем ужесточить её после того, как другой код начал от неё зависеть.
Преимущества
- Инкапсуляция — объединяйте данные с методами, которые с ними работают, и не позволяйте остальной программе вмешиваться. См. Классы и объекты PHP.
- Скрытие информации — вызывающий код зависит от вашего публичного API, а не от внутренних деталей, поэтому вы можете изменить реализацию класса, не ломая его пользователей.
- Инварианты — поскольку записи проходят через ваши методы, вы можете гарантировать, что объект всегда находится в валидном состоянии.
Резюме
Ключевое слово private ограничивает доступ к члену класса только тем классом, который его объявляет — ни его подклассам, ни внешнему миру. Это стандартный инструмент инкапсуляции: скрывайте внутренние данные и вспомогательные методы, предоставляйте небольшой валидированный публичный API и поддерживайте объекты в согласованном состоянии. Используйте protected, когда подклассам нужен доступ, и public — только для предназначенного интерфейса.