Константы классов в PHP OOP
Узнайте о константах классов PHP: объявление с const, управление видимостью, массивы и выражения в значениях, доступ через self, static или имя класса.
Константа класса — это фиксированное именованное значение, которое принадлежит классу, а не отдельному объекту. Она определяется один раз, не может быть переназначена во время выполнения и является общей для всех экземпляров класса. Константы — это способ давать осмысленные имена «магическим» значениям, от которых зависит ваш код — ставке налога, строке статуса, версии API — чтобы они находились в одном месте, а не были разбросаны как литералы.
В этой главе рассказывается, как объявлять константы класса с помощью const, как читать их через self, static и имя класса, как управлять их видимостью и как они ведут себя при наследовании и в интерфейсах. Все примеры ниже работают на PHP 8.
Зачем использовать константы класса?
Используйте константу класса, когда значение известно заранее и никогда не должно меняться во время выполнения скрипта:
- Единственный источник истины. Определите значение, например
Order::SHIPPING_FEE, один раз — каждый вызывающий код будет читать то же число. - Читаемость.
Circle::PIговорит гораздо больше, чем голое3.14159, зарытое в вычислениях. - Безопасность. PHP отвергает любую попытку переназначить константу, так что опечатка не сможет её молча перезаписать.
- Объект не нужен. Поскольку константа принадлежит классу, её можно читать без создания экземпляра.
Константы класса отличаются от обычных переменных двумя важными способами: они пишутся без знака доллара (MAX_USERS, а не $MAX_USERS) и являются неизменяемыми после определения.
Определение константы класса
Объявите константу внутри тела класса с помощью ключевого слова const, имени (по соглашению UPPER_SNAKE_CASE) и значения:
<?php
class MyClass {
const CONSTANT = 'constant value';
public function showConstant() {
echo self::CONSTANT . "\n";
}
}Это определяет CONSTANT в MyClass. Константа класса отличается от глобальной константы, созданной с помощью define(): const принадлежит классу и доступна через ::, тогда как define() регистрирует имя в глобальной области видимости.
Значение может быть константным выражением — вычислением, которое PHP может разрешить во время компиляции — и даже массивом:
<?php
class Circle {
const PI = 3.14159;
const TWO_PI = self::PI * 2; // built from another constant
const UNITS = ['mm', 'cm', 'm'];
}
echo Circle::TWO_PI . "\n"; // 6.28318
echo Circle::UNITS[1] . "\n"; // cmЧто вы не можете использовать — так это всё, что известно только во время выполнения: вызовы функций, экземпляры объектов или $переменные не допускаются в значении константы.
Доступ к константе класса
Способ чтения константы зависит от того, где вы находитесь:
- Снаружи класса используйте имя класса:
MyClass::CONSTANT. - Внутри класса используйте ключевое слово
self:self::CONSTANT.
constant value
constant valueПервая строка читает константу статически через имя класса — объект не нужен. Вторая обращается через метод экземпляра, использующий self::CONSTANT. Обратите внимание, что к константам обращаются с помощью ::, но никогда через оператор объекта ->, который используется для свойств.
Управление видимостью
Начиная с PHP 7.1, константы класса принимают те же модификаторы видимости, что и свойства и методы: public (по умолчанию), protected и private. Это позволяет скрывать детали реализации, которые принадлежат классу, но не должны быть видны снаружи.
<?php
class Config {
public const VERSION = '2.0';
protected const API_KEY = 'secret-123';
private const SALT = 'x9f2';
public function describe(): string {
return self::VERSION . ' / ' . self::API_KEY . ' / ' . self::SALT;
}
}
echo Config::VERSION . "\n"; // 2.0 — public, readable anywhere
$c = new Config();
echo $c->describe() . "\n"; // 2.0 / secret-123 / x9f2Здесь Config::VERSION доступна везде, тогда как API_KEY и SALT можно получить только изнутри класса (или, для protected, его подклассов). Попытка прочитать Config::SALT снаружи вызовет ошибку.
Константы и наследование
Подклассы наследуют константы родителя и могут их переопределять. Ключевое слово, используемое для чтения константы, определяет, какую версию вы получите:
self::NAMEразрешается при написании кода — оно всегда означает константу в классе, где определён метод.static::NAMEразрешается во время выполнения относительно фактического класса, который был вызван. Это называется поздним статическим связыванием.
<?php
interface HasStatus {
const ACTIVE = 'active'; // interface constants are always public
}
class Order implements HasStatus {
const SHIPPING_FEE = 5.00;
public function status(): string {
return self::ACTIVE;
}
}
class ExpressOrder extends Order {
const SHIPPING_FEE = 15.00;
public function fee(): float {
return static::SHIPPING_FEE; // uses the called class's value
}
}
echo Order::ACTIVE . "\n"; // active (inherited from the interface)
echo (new ExpressOrder())->fee() . "\n"; // 15
echo (new ExpressOrder())->status() . "\n"; // activeИнтерфейсы тоже могут объявлять константы — они неявно public и разделяются каждым реализующим классом. Если вам нужна константа, которую подклассы не должны переопределять, пометьте её как final (PHP 8.1+): final const ID = 100;. PHP 8.3 также добавил типизированные константы, например const string LABEL = 'base';.
Подробнее о поведении подклассов см. Наследование в PHP, а о связанной возможности данных на уровне класса — Статические свойства PHP.
Типичные ошибки
- Без знака доллара.
const RATE = 0.2;— написание$RATEявляется синтаксической ошибкой. ::, а не->. К константам всегда обращаются с помощью оператора разрешения области видимости.- Значения времени выполнения отвергаются. Значение константы должно быть константным выражением;
const NOW = time();не скомпилируется. selfиstatic. Используйтеstatic::, когда подкласс должен иметь возможность переопределить значение; в противном случаеself::— более безопасный и предсказуемый выбор.
Заключение
Константы класса дают вам именованные, неизменяемые значения в области видимости класса, определяемые с помощью const и читаемые через ::. Используйте их для централизации фиксированных значений, улучшения читаемости и защиты данных, которые никогда не должны изменяться во время выполнения. Комбинируйте их с модификаторами видимости для скрытия внутренних деталей и помните о различии между self и static, когда появляется наследование.