Детальная информация о модификаторах доступа в PHP. Как их правильно использовать?

детальная информация о модификаторах доступа в php. как их правильно использовать?

Для чего нужны модификаторы доступа

Мы уже встречались с предметом изучения данной статьи, рассматривая работу со свойствами классов и использование методов. Перед их именами добавляются специальные ключевые слова, которые в PHP принято называть модификаторами доступа. Они описывают способы взаимодействия. Например, можно ли получить значение свойства из окружения или только внутри методов класса.

Регулирование доступа к значениям свойств или вызовам методов позволяет контролировать поведение экземпляра класса, исключая случайные события. Допустим, ваш объект хранит в своих свойствах параметры подключения к базе данных. Если доступ к ним открыт из окружения, то случайное изменение одного из параметров обязательно обернется ошибкой.

В PHP определение модификатора метода можно записать с помощью следующего выражения «модификатор_доступа function имяМетода(/* список параметров */) { /* программный код */ }». По аналогии модификация свойства выглядит следующим образом «модификатор_доступа $имяСвойства = значение_свойства;».

Заметка
Некоторые модификаторы доступа влияют не только на способы взаимодействия со свойствами или методами, но также изменяют принципы их наследования.

Публичные свойства и методы (модификатор public)

Указание модификатора public не накладывает никаких ограничений на использование свойств или методов. Они доступны как снаружи, так и внутри объекта. При наследовании свойства и методы будут закреплены за дочерним классом.

//Создание класса "Велосипед"
class Bicycle
{
    //Модификаторы свойств public
    public $color = 'Желтый';
    public $type = 'Горный';

    //Модификаторы методов public
    public function rideUphill()
    {
        echo "Едем в гору...";
    }

    public function getInfo()
    {
        echo "Цвет: {$this->color}<br>";
        echo "Тип: {$this->type}<br>";
    }
}

//Создаем объект и меняем его
//свойства прямо из окружения
$bicycle = new Bicycle();
$bicycle->getInfo();
/*
* Результат:
* Цвет: Желтый
* Тип: Горный
*/

$bicycle->color = 'Зеленый';
$bicycle->type = 'Городской';
$bicycle->getInfo();
/*
* Результат:
* Цвет: Зеленый
* Тип: Городской
*/

Заметка
В кругах профессиональных PHP-программистов сложилась определенная практика. Как правило, свойства класса не должны иметь модификатор public. Изменение и получение их значений происходит через специальные методы. Например, свойство $title, содержащее заголовок статьи, можно изменить с помощью метода setTitle(), а получить с помощью getTitle(). Это соответствует принципам инкапсуляции.

Защищенные свойства и методы (модификатор protected)

Модификатор protected сделает невозможным доступ к значению свойства или вызов метода из окружения. Оперировать ими можно только внутри других методов объекта. При наследовании, они будут закреплены за дочерним классом.

В PHP попытка вызова методов или установки свойств, имеющих модификатор protected, вызовет фатальную ошибку.

//Определение класса "Тайное укрытие"
class HidingPlace
{
    //Защищенное свойство контейнер
    protected $container = [];

    //Открытый метод добавления содержимого
    //в контейнер
    public function insertContainer($value)
    {
        //если контейнер содержит меньше двух
        //элементов, то добавляем новый. Иначе
        //обнуляем его и добавляем.
        if (count($this->container) < 2) {
            $this->container[] = $value;

        } else {
            $this->clearContainer();
            $this->container[] = $value;
        }
    }

    //Открытый метод получения состояния
    public function getContainerInfo()
    {
        var_dump($this->container);
    }

    //Закрытый метод очистки контейнера
    protected function clearContainer()
    {
        $this->container = [];
    }
}

//Создаем объект и демонстрируем работу
$hidingPlace = new HidingPlace();

$hidingPlace->insertContainer('Золото');
$hidingPlace->insertContainer('Серебро');
$hidingPlace->getContainerInfo();
/*
* Результат:
* array(3) {
*     [0]=> string(12) "Золото"
*     [1]=> string(14) "Серебро"
* }
*/

//Добавление еще одного элемента выполнит
//вызов закрытой функции сброса контейнера
$hidingPlace->insertContainer('Алмазы');
$hidingPlace->getContainerInfo();
/*
* Результат:
* array(3) {
*     [0]=> string(12) "Алмазы"
* }
*/

//Попытки получить защищенное свойство и
//вызвать метод сброса контейнера
$hidingPlace->container = ['новый элемент'];
$hidingPlace->clearContainer();
/*
* Результат:
* Фатальные ошибки!
*/

Приватные свойства и методы (модификатор private)

Данный модификатор по основному принципу действия схож с protected. Его отличительной чертой является то, что свойства и методы, установленные в private, не наследуются. Если вы вызовите такой метод или попробуете получить доступ к значению свойства в дочернем классе, программный код завершится с ошибкой.

//Определение класса "Автомобиль"
class Car
{
    //Приватный метод "Зажигание"
    private function ignition()
    {
        echo "Автомобиль завелся<br>";
    }

    //Публичный метод "движение" вызывает
    //приватный метод зажигания
    public function drive()
    {
        $this->ignition();
        echo 'Поехали на прогулку<br>';
    }
}

//Определение класса "Грузовик"
class Truck extends Car
{
    //Публичный метод "движение" пытается
    //вызвать приватный метод родительского
    //класса
    public function drive()
    {
        $this->ignition();
        echo 'Развозим товары<br>';
    }
}

//Создаем объекты и демонстрируем работу
$simpleCar = new Car();
$heavyTruck = new Truck();

$simpleCar->drive();
/*
* Результат:
* Автомобиль завелся
* Поехали на прогулку
*/

$heavyTruck->drive();
/*
* Результат:
* Фатальная ошибка!
*/

Модификаторы доступа констант

В PHP версии 7.1 появилась возможность добавлять модификаторы доступа для констант, определенных внутри класса. Однако их явное указание не обязательно. Константа без модификатора по умолчанию относится к public.

//Определение класса "Сообщения"
class Messages
{
    //Публичные константы
    const RUNTIME_ERROR = 'Ошибка во время исполнения';
    public const ERROR = 'Фатальная ошибка';

    //Защищенная константа
    protected const SUCCESS = 'Работа успешно завершена';

    //Приватная константа
    private const WARNING = 'Произошла некритичная ошибка';
}

Последние публикации