Конструктор PHP это метод с именем __construct(). PHP вызывает его автоматически, когда вы пишете new ClassName(...), а аргументы в скобках становятся его параметрами, поэтому объект начинает жизнь с уже заданными значениями.
Без конструктора вы создавали бы пустой объект и задавали каждое свойство потом, и ничто не помешало бы забыть одно из них. С конструктором new User() без аргументов вызывает ArgumentCountError.
Продвижение свойств в конструкторе
Объявить свойство, указать его параметром и присвоить $this->name = $name значит повторить каждое имя трижды. Начиная с PHP 8.0 ключевое слово видимости перед параметром конструктора делает всё это разом:
Продвинутый параметр может быть и readonly (public readonly string $id), это самый короткий способ записать неизменяемый объект-значение. Продвинутые и обычные параметры можно смешивать, а в теле конструктора по-прежнему может быть код, который выполняется после присваивания продвинутых свойств.
Значения по умолчанию и именованные аргументы
Параметры конструктора принимают значения по умолчанию, как у любой функции. Параметры со значениями по умолчанию идут после обязательных. С именованными аргументами (PHP 8.0) вызывающий код может сразу указать нужную опцию, не повторяя все значения по умолчанию перед ней:
Запустите: в выводе есть HTML, поэтому вкладка Page показывает три отрисованные кнопки, а вкладка Output теги, которые напечатал PHP. Обратите внимание на скобки в (new Button('Save'))->render(): начиная с PHP 8.4 они необязательны, но PHP 8.3 они нужны.
Проверка аргументов в конструкторе
Конструктор не может вернуть false или код ошибки: всё, что он возвращает, игнорируется. Чтобы отклонить неверные данные, выбросьте исключение. Тогда объект вообще не создаётся, и остальная программа может доверять каждому полученному Temperature.
Перехват таких исключений подробнее описан на странице try catch.
Несколько конструкторов через статические фабричные методы
В PHP нет перегрузки конструкторов: один класс, один __construct. Когда объект можно собрать из разных входных данных (строка даты, массив, временная метка), добавьте именованные статические методы, которые готовят аргументы и вызывают new static(...). Если сделать конструктор private, всем придётся идти через фабрики.
new Color(1, 2, 3) снаружи класса теперь выбрасывает Error ("Call to private Color::__construct() from global scope"). Почему здесь используется new static, а не new self, объясняет страница о static.
Вызов конструктора родителя через parent::__construct
Когда дочерний класс определяет свой конструктор, конструктор родителя сам не выполняется. Вызовите его через parent::__construct(...), обычно первым, чтобы свойства родителя были заданы до того, как дочерний класс добавит свои:
Если у дочернего класса конструктора нет вовсе, PHP использует родительский, и new Truck('Volvo') передал бы аргументы прямо в Vehicle::__construct. Подробнее об этом в разделе о наследовании.
Забытый parent::__construct
Эта ошибка не даёт сообщения в той строке, где возникает. Конструктор дочернего класса выполняется, типизированные свойства родителя остаются неинициализированными, а программа падает позже, там, где их впервые читают:
Добавьте parent::__construct(); первой строкой в Post::__construct и запустите снова: код выведет дату. Связанный метод __destruct() выполняется, когда исчезает последняя ссылка на объект или завершается скрипт. В повседневном коде он нужен редко, потому что PHP сам закрывает файлы и освобождает память в конце каждого запроса.
Часто задаваемые вопросы
Что такое __construct в PHP?
__construct() это конструктор: метод, который PHP вызывает автоматически сразу после того, как new создал объект. Аргументы, переданные в new User('Ada', 36), попадают в __construct(string $name, int $age), который обычно сохраняет их в свойствах.
Что такое продвижение свойств в конструкторе PHP?
Начиная с PHP 8.0 ключевое слово видимости у параметра конструктора объявляет свойство и присваивает его за один шаг: public function __construct(private string $name) {} равносильно объявлению private string $name; и записи $this->name = $name; в теле.
Может ли у класса PHP быть несколько конструкторов?
Нет. В PHP нет перегрузки методов, поэтому у класса один __construct. Используйте необязательные параметры со значениями по умолчанию или добавьте статические фабричные методы вроде public static function fromArray(array $data): static, которые вызывают new static(...) с нужными аргументами.
Вызывается ли конструктор родителя в PHP автоматически?
Только когда у дочернего класса нет своего конструктора. Если дочерний класс определяет __construct, конструктор родителя не выполняется, пока вы сами не вызовете parent::__construct(...), обычно первой строкой.
Может ли конструктор PHP вернуть значение?
Нет. new всегда даёт объект, а то, что возвращает __construct, игнорируется. Чтобы сообщить о проблеме, выбросьте исключение из конструктора, например throw new InvalidArgumentException('Age must be positive').