Свойства и классы для чтения

Последнее обновление: 25.11.2023

Константы

Кроме переменных внутри класса можно определять константы. Значение констант устанавливается непосредственно при объявлении:

<?php
class Person
{ 
    public $name, $age;
    const maxAge = 110;     // константа maxAge
    function __construct($name, $age)
    {
        $this->name = $name;
        if($age > Person::maxAge) $age = Person::maxAge;
        $this->age = $age;
    }
    function print()
    {
        echo "Имя: $this->name Возраст: $this->age<br>";
    }
}

$tom = new Person("Tom", 38);
$bob = new Person("Bob", 138);
$tom->print();
$bob->print();
// обращение к статическому свойству 
echo "Максимальный возраст: " . Person::maxAge . "<br>";
?>

Здесь в классе Person определена константа maxAge, которая имеет значение 110. Пусть она представляет максимально возможный возраст. В конструкторе мы применяем эту константу - если переданный возраст больше, то усекаем его до maxAge. Для обращения к константе классе внутри и вне класса используется синтаксис:

имя_класса::имя_константы

Например:

Person::maxAge

Вывод браузера:

Имя: Tom Возраст: 38
Имя: Bob Возраст: 110
Максимальный возраст: 110

Стоит отметить, что начиная с версии PHP 8.3 для константы также можно явным образом установить тип данных:

const int maxAge = 110;     // константа maxAge имеет тип int

Свойства для чтения

Иногда необходимы свойства, которые не должны менять своего значения. Начиная с версии 8.1 в PHP была добавлена возможность определять свойства для чтения. Подобные свойства предваряются ключевым словом readonly. Это позволяет гарантировать, что значение свойства не изменится. Таким свойствам можно передать значение только один раз внутри класса, в котором они определены (обычно это делается в конструкторе класса). От констант такие свойства отличаются тем, что их можно установить в конструкторе.

Рассмотрим небольшой пример:

<?php
class Person
{ 
    public readonly string $name;
    public $age;
      
    public function __construct($name, $age)
    {
        $this->name = $name;
        $this->age = $age;
    }
}
$tom = new Person("Tom", 38);
$tom->age = 22;             // значение свойства $age можно поменять

// $tom->name = "Bob";     // значение свойства $name нельзя поменять, так как оно только для чтения

echo "Name: $tom->name";  // получить значение свойства $name можно
?>

Здесь определен класс Person, в котором есть два свойства. При этом свойство $name определено как свойство для чтения с модификатором readonly

public readonly string $name;

Кроме того, если свойство определяется как свойство только для чтения, то для него необходимо явным образом указать тип данных. Так, в данном случае свойство name представляет тип string, то есть строку.

В конструкторе свойствам $name и $age присваиваются начальные значения. Однако после этого мы не сможем изменить значение свойства $name, даже внутри этого же класса. Мы можем только получить его значение. И если бы мы попробовали бы изменить его значение, например:

$tom->name = "Bob"; 

то мы столкнулись бы с ошибкой:

Fatal error: Uncaught Error: Cannot modify readonly property Person::$name 

Стоит отметить, что свойствам для чтения даже нельзя установить значение по умолчанию при определении, поскольку в этом случае оно было бы аналогично константе:

class Person
{ 
    public readonly string $name = "undefined"; // ! Ошибка
    public $age = 18;                           // Норм

Конструктор - не единственное место, где можно установить свойство для чтения - это может быть любой метод класса. Например, можно сделать так:

<?php
class Person
{ 
    public readonly string $name;
    public $age;
    public function init(){
        $this->name = "Bob";
    }
}
$tom = new Person();
$tom -> init();         // инициализация свойства $name 
echo "Name: $tom->name";  // Name: Bob
?>

Здесь установка значения производится в методе init(). Однако в этом случае мы можем столкнуться с проблемой, что к свойству $name будет обращение до вызова метода init(), и соответственно мы столкнемся с ошибкой. Поэтому конструктор является наиболее оптимальным местом для инициализации свойств для чтенияю.

Классы для чтения

Начиная с версии 8.2 PHP позволяет определять классы для чтения. Такой класс определяется с помощью ключевого слова readonly. Свойства таких классов по умолчанию являются свойствами, доступными только для чтения. Это гарантирует, что никакое из свойств объекта не сможет изменить значение. Например, следующий класс:

readonly class Person
{ 
    public string $name;
    public int $age;
    public function __construct($name, $age)
    { 
        $this->name = $name; 
        $this ->age = $age;
    }
}

будет эквивалентен следующему:

class Person
{ 
    public readonly string $name;
    public readonly int $age;
    public function __construct($name, $age)
    { 
        $this->name = $name; 
        $this ->age = $age;
    }
}

При этом для свойств класса для чтения также надо явным образом указывать тип данных. Кроме того, при наследовании производный класс также должен быть классом только для чтения.

В остальном классы для чтения используются также как и обычные классы:

<?php
readonly class Person
{ 
    public function __construct(public string $name, public int $age)
    {}
}
$tom = new Person("Tom", 38);
// получить значения свойств можно
echo "Name: $tom->name  Age: $tom->age";  // Name: Tom Age: 38
// изменить значения свойств нельзя
// $tom->name = "Tomas";  // !ошибка
?>
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850