Свойства
Переменные, которые являются членами класса, называются свойства.
Также их называют, используя другие термины, таких как поля,
но в рамках этой документации,
мы будем называть их свойствами.
Они определяются с использованием хотя бы одного необязательного (за исключением readonly
-свойств) модификатора
(например, Область видимости, Ключевое слово static или,
начиная с PHP 8.1.0, readonly), начиная с PHP 7.4,
за которым следует необязательное объявление типа, за которым следует обычное объявление переменной.
Это объявление может содержать инициализацию, но
эта инициализация должна быть постоянным значением.
Замечание:
Устаревший способ объявления свойств класса —
использование ключевого слова var
вместо модификатора.
Замечание:
Свойство, объявленное без модификатора Область видимости,
будет объявлено как public
.
В пределах методов класса доступ к нестатическим свойствам может быть
получен с помощью ->
(объектного оператора):
$this->property (где property
- имя свойства).
Доступ к статическим свойствам осуществляется с помощью ::
(двойного двоеточия): self::$property. Дополнительную информацию о различии
статических и нестатических свойств смотрите в разделе
Ключевое слово static.
Псевдопеременная $this доступна внутри
любого метода класса, когда этот метод вызывается из контекста объекта.
$this - значение вызывающего объекта.
Пример #1 Определение свойств
<?php
class SimpleClass
{
public $var1 = 'hello ' . 'world';
public $var2 = <<<EOD
hello world
EOD;
public $var3 = 1+2;
// неправильное определение свойств:
public $var4 = self::myStaticMethod();
public $var5 = $myVar;
// правильное определение свойств:
public $var6 = myConstant;
public $var7 = [true, false];
public $var8 = <<<'EOD'
hello world
EOD;
// Без модификатора области видимости:
static $var9;
readonly int $var10;
}
?>
Замечание:
Существуют различные функции для обработки классов и объектов.
Смотрите справочник по функций для классов/объектов.
Объявления типов
Начиная с PHP 7.4.0, определения свойств могут включать Объявления типов,
за исключением типа callable.
Пример #2 Пример использования типизированных свойств
<?php
class User
{
public int $id;
public ?string $name;
public function __construct(int $id, ?string $name)
{
$this->id = $id;
$this->name = $name;
}
}
$user = new User(1234, null);
var_dump($user->id);
var_dump($user->name);
?>
Результат выполнения приведённого примера:
Перед обращением к типизированному свойству у него должно быть задано значение, иначе будет выброшено исключение
Error.
Пример #3 Обращение к свойствам
<?php
class Shape
{
public int $numberOfSides;
public string $name;
public function setNumberOfSides(int $numberOfSides): void
{
$this->numberOfSides = $numberOfSides;
}
public function setName(string $name): void
{
$this->name = $name;
}
public function getNumberOfSides(): int
{
return $this->numberOfSides;
}
public function getName(): string
{
return $this->name;
}
}
$triangle = new Shape();
$triangle->setName("triangle");
$triangle->setNumberofSides(3);
var_dump($triangle->getName());
var_dump($triangle->getNumberOfSides());
$circle = new Shape();
$circle->setName("circle");
var_dump($circle->getName());
var_dump($circle->getNumberOfSides());
?>
Результат выполнения приведённого примера:
string(8) "triangle"
int(3)
string(6) "circle"
Fatal error: Uncaught Error: Typed property Shape::$numberOfSides must not be accessed before initialization
Readonly-свойства
Начиная с PHP 8.1.0, свойство можно объявить с помощью модификатора readonly
, который предотвращает изменение свойства после инициализации.
Пример #4 Примеры readonly-свойств
<?php
class Test {
public readonly string $prop;
public function __construct(string $prop) {
// Правильная инициализация.
$this->prop = $prop;
}
}
$test = new Test("foobar");
// Правильное чтение.
var_dump($test->prop); // string(6) "foobar"
// Неправильное переопределение. Не имеет значения, что присвоенное значение такое же.
$test->prop = "foobar";
// Ошибка: невозможно изменить readonly-свойство Test::$prop
?>
Замечание:
Модификатор readonly может применяться только к типизированным свойствам.
Readonly-свойство без ограничений типа можно создать с помощью типа Mixed.
Замечание:
Статические readonly-свойства не поддерживаются.
Readonly-свойство можно инициализировать только один раз и только из области, в которой оно было объявлено.
Любое другое присвоение или изменение свойства приведёт к исключению Error.
Пример #5 Неправильная инициализация readonly-свойств
<?php
class Test1 {
public readonly string $prop;
}
$test1 = new Test1;
// Неправильная инициализация за пределами закрытой области.
$test1->prop = "foobar";
// Ошибка: не удаётся инициализировать readonly-свойство Test1::$prop из глобальной области
?>
Замечание:
Указание явного значения по умолчанию для readonly-свойств не допускается, потому что readonly-свойство со значением по умолчанию, по сути, то же самое, что и константа и поэтому не особенно полезно.
<?php
class Test {
// Ошибка: у readonly-свойства Test::$prop не может быть значения по умолчанию
public readonly int $prop = 42;
}
?>
Замечание:
Readonly-свойства не могут быть уничтожены с помощью unset() после их инициализации.
Однако можно уничтожить readonly-свойство до инициализации из области, в которой было объявлено свойство.
Модификации не обязательно являются простыми присвоениями, всё перечисленное ниже также приведёт к исключению Error:
<?php
class Test {
public function __construct(
public readonly int $i = 0,
public readonly array $ary = [],
) {}
}
$test = new Test;
$test->i += 1;
$test->i++;
++$test->i;
$test->ary[] = 1;
$test->ary[0][] = 1;
$ref =& $test->i;
$test->i =& $ref;
byRef($test->i);
foreach ($test as &$prop);
?>
Однако readonly-свойства не исключают внутренней изменчивости. Объекты (или ресурсы), хранящиеся в readonly-свойствах по-прежнему могут быть изменены внутри:
<?php
class Test {
public function __construct(public readonly object $obj) {}
}
$test = new Test(new stdClass);
// Правильное внутреннее изменение.
$test->obj->foo = 1;
// Неправильное переопределение.
$test->obj = new stdClass;
?>
Динамические свойства
При попытке присвоить несуществующее свойство объекту (object),
PHP автоматически создаст соответствующее свойство.
Это динамически созданное свойство будет доступно
только для данного экземпляра класса.
Внимание
Динамические свойства устарели, начиная с PHP 8.2.0.
Вместо этого рекомендуется объявлять свойство.
Для работы с произвольными именами свойств,
класс должен реализовать магические методы
__get() и __set().
В крайнем случае, класс можно пометить атрибутом #[\AllowDynamicProperties]
.