Конструктор и инкапсуляция
Объект должен появляться сразу в готовом, правильном состоянии и не позволять испортить свои данные снаружи. За первое отвечает конструктор, за второе — модификаторы доступа.
Конструктор
Метод __construct() вызывается автоматически при создании объекта. Аргументы передаются в скобках после имени класса:
<?php
class Product
{
public string $title;
public float $price;
public function __construct(string $title, float $price)
{
$this->title = $title;
$this->price = $price;
}
}
$product = new Product('Чай', 150);
echo $product->title; // ЧайКороткая запись
Объявить свойство и заполнить его из параметра можно одной строкой — достаточно указать модификатор доступа прямо в параметре конструктора:
<?php
class Product
{
public function __construct(
public string $title,
public float $price,
) {}
}
$product = new Product('Чай', 150);
echo "{$product->title}: {$product->price}"; // Чай: 150Этот класс делает то же, что и предыдущий, но без повторов.
private
Свойство с модификатором private доступно только внутри класса. Менять его можно лишь через методы, а они могут проверять данные:
<?php
class Account
{
private int $balance = 0;
public function deposit(int $amount): void
{
if ($amount <= 0) {
return;
}
$this->balance += $amount;
}
public function balance(): int
{
return $this->balance;
}
}
$account = new Account();
$account->deposit(100);
$account->deposit(-50);
echo $account->balance(); // 100Отрицательное пополнение отклонено. Сокрытие данных за методами называется инкапсуляцией: объект сам следит за тем, чтобы его состояние оставалось правильным.
Только для чтения
Свойство readonly можно задать один раз, в конструкторе. Попытка изменить его позже вызовет ошибку:
<?php
class Point
{
public function __construct(
public readonly int $x,
public readonly int $y,
) {}
}
$point = new Point(2, 3);
echo $point->x; // 2Такие свойства удобны для данных, которые не должны меняться после создания объекта.
Константы класса
Значение, общее для всех объектов и неизменное, объявляют константой. Внутри класса к ней обращаются через self:::
<?php
class Circle
{
public const PI = 3.14159;
public function __construct(private float $radius) {}
public function area(): float
{
return self::PI * $this->radius ** 2;
}
}
echo (new Circle(2))->area(); // 12.56636Частая ошибка
Делать все свойства public проще, но тогда любой код может записать в объект что угодно. Начинайте с private и открывайте только то, что действительно нужно снаружи.