PHP
#php#php-8-3#override#attributes#inheritance

PHP 8.3: атрибут #[\Override] при переопределении методов

Использование встроенного атрибута #[\Override] для проверки переопределения метода родителя — защита от опечаток и смены сигнатуры.

Как использовать

  1. Перед объявлением метода дочернего класса или метода, реализующего интерфейс, добавьте атрибут #[\Override].
  2. PHP проверит, что в родителе или интерфейсе есть метод с тем же именем; при опечатке или переименовании родителя — Fatal error.
  3. Атрибут встроенный, подключать ничего не нужно (PHP 8.3+).

При переопределении метода в дочернем классе или реализации метода интерфейса легко допустить опечатку в имени или не заметить переименование метода в родителе. В результате вызывается не переопределённый метод, а унаследованный (или вообще не тот) — баг проявляется только в рантайме. В PHP 8.3 добавлен встроенный атрибут #[\Override]: если пометить им метод, движок проверит, что в родительском классе или реализуемом интерфейсе есть метод с таким же именем. Проблема: без атрибута опечатка (например handl вместо handle) даёт тихий баг. Симптомы: ожидаемое поведение не срабатывает, отлаживать сложно. Ниже — пример использования и ошибка при несовпадении имени по документации PHP 8.3 Override; проверка и типичные ошибки.

Решение

Атрибут #[\Override] помечает метод как переопределяющий родительский или реализующий интерфейс. PHP проверяет наличие совпадающего метода у родителя/интерфейса.

<?php

class BaseHandler
{
    public function handle(): void
    {
        // базовая логика
    }
}

class OrderHandler extends BaseHandler
{
    #[\Override]
    public function handle(): void
    {
        // переопределённая логика заказа
    }
}

Ошибка при опечатке в имени метода:

class OrderHandler extends BaseHandler
{
    #[\Override]
    public function handl(): void  // опечатка: handl вместо handle
    {
    }
}
// Fatal error: OrderHandler::handl() has #[\Override] attribute,
// but no matching parent method exists

В модулях Bitrix, интеграциях и любом коде с наследованием помечайте переопределённые методы #[\Override], чтобы при переименовании родителя или опечатке сразу получить Fatal error, а не тихий баг. Атрибут встроенный; применяется только к методам. Подходит и для методов, реализующих интерфейс.

Проверка

  1. Корректное переопределение — сохраните пример с BaseHandler и OrderHandler (с правильным именем handle), выполните:
php -l override_example.php
php override_example.php

Ошибок быть не должно.

  1. Ошибка при опечатке — в дочернем классе переименуйте метод в handl, оставьте #[\Override]. Запуск должен завершиться Fatal error с текстом «no matching parent method exists».

  2. Реализация интерфейса — пометьте метод, реализующий метод интерфейса, атрибутом #[\Override]. При несовпадении имени с методом интерфейса также будет Fatal error.

Типичные ошибки

  • Атрибут на метод, который не переопределяет родителя — если вы ошиблись и такого метода в родителе нет (или переименовали родителя), PHP выдаст Fatal error. Это ожидаемо: атрибут как раз для такой проверки.
  • PHP меньше 8.3 — атрибут Override появился в 8.3. На старых версиях будет синтаксическая ошибка или «Unknown attribute». Проверьте версию: php -v.
  • Использование только в дочерних классах — атрибут имеет смысл только у методов, которые реально переопределяют родителя или реализуют интерфейс. На обычном методе без родителя/интерфейса с таким именем получите ошибку.

Где применять

  • Bitrix и интеграции: обработчики событий, классы, наследующие Bitrix API, обёртки над заказами и сущностями — везде, где переопределяете методы родителя.
  • Любой PHP 8.3+ с наследованием: формы, хендлеры, сервисы. Рекомендуется помечать все переопределения, чтобы рефакторинг родителя не ломал код тихо.

Связанные сниппеты: PHP 8.5: клонирование заказа со статусом, Изменить статус заказа D7 и сохранить, Option::get с union type.