Кроме переменных внутри класса можно определять константы. Значение констант устанавливается непосредственно при объявлении:
<?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"; // !ошибка ?>