Можно ли объявлять константы в интерфейсе?

Ответ

Да, начиная с PHP 8.1, в интерфейсах можно объявлять константы. Они являются публичными, неизменяемыми и доступны через имя интерфейса или класс, реализующий этот интерфейс.

Пример объявления и использования:

interface Logger {
    public const LOG_LEVEL_ERROR = 1;
    public const LOG_LEVEL_WARNING = 2;

    public function log(string $message, int $level): void;
}

class FileLogger implements Logger {
    public function log(string $message, int $level): void {
        if ($level === Logger::LOG_LEVEL_ERROR) {
            // Обработка ошибки
        }
    }
}

// Доступ через интерфейс
echo Logger::LOG_LEVEL_ERROR; // 1
// Доступ через реализующий класс
echo FileLogger::LOG_LEVEL_WARNING; // 2

Ключевые особенности:

  • Константы в интерфейсах всегда public (модификатор можно не указывать).
  • Нельзя объявлять protected или private константы.
  • Константы наследуются всеми классами, реализующими интерфейс.
  • Хотя технически константу можно переопределить в классе с помощью const, это считается плохой практикой, нарушающей контракт интерфейса.

Ответ 18+ 🔞

А, ну это про константы в интерфейсах! Да, с PHP 8.1 такое можно делать, ёпта. Раньше-то нихуя нельзя было, а теперь — пожалуйста. Они там публичные, неизменяемые, и достучаться до них можно либо через сам интерфейс, либо через класс, который этот интерфейс реализует.

Вот тебе пример, смотри:

interface Logger {
    public const LOG_LEVEL_ERROR = 1;
    public const LOG_LEVEL_WARNING = 2;

    public function log(string $message, int $level): void;
}

class FileLogger implements Logger {
    public function log(string $message, int $level): void {
        if ($level === Logger::LOG_LEVEL_ERROR) {
            // Обработка ошибки
        }
    }
}

// Доступ через интерфейс
echo Logger::LOG_LEVEL_ERROR; // 1
// Доступ через реализующий класс
echo FileLogger::LOG_LEVEL_WARNING; // 2

А теперь главное, что надо запомнить, чтобы не облажаться:

  • Эти константы в интерфейсах — они всегда public. Даже если ты этот модификатор не напишешь, они всё равно публичные будут. Хуй с горы, так сказать.
  • Забудь про protected или private — нихуя не выйдет, только public.
  • Все классы, которые интерфейс реализуют, эти константы наследуют автоматом.
  • И вот что важно: технически-то ты можешь переопределить константу в классе, объявив свою const. Но это, блядь, будет такая пиздопроебибна с точки зрения архитектуры! Ты же по сути контракт интерфейса ломаешь. Не делай так, а то потом сам от себя охуеешь, когда начнёшь искать, откуда какое значение приползло.