Understanding PHP OOP Constants
Learn PHP class constants: declare with const, control visibility, use arrays and expressions as values, and access via self, static, or the class name.
A class constant is a fixed, named value that belongs to a class rather than to any single object. It is defined once, can never be reassigned at runtime, and is shared by every instance of the class. Constants are how you give meaningful names to the "magic" values your code depends on — a tax rate, a status string, an API version — so they live in one place instead of being scattered as literals.
This chapter covers how to declare class constants with const, how to read them with self, static, and the class name, how to control their visibility, and how they behave with inheritance and interfaces. Every example below runs on PHP 8.
Why use class constants?
Reach for a class constant when a value is known ahead of time and must never change while the script runs:
- Single source of truth. Define a value such as
Order::SHIPPING_FEEonce; every caller reads the same number. - Readability.
Circle::PIsays far more than a bare3.14159buried in a calculation. - Safety. PHP rejects any attempt to reassign a constant, so a typo can't silently overwrite it.
- No object needed. Because a constant belongs to the class, you can read it without creating an instance.
Class constants differ from regular variables in two important ways: they are written without a dollar sign (MAX_USERS, not $MAX_USERS), and they are immutable once defined.
Defining a class constant
Declare a constant inside the class body with the const keyword, a name (conventionally UPPER_SNAKE_CASE), and a value:
<?php
class MyClass {
const CONSTANT = 'constant value';
public function showConstant() {
echo self::CONSTANT . "\n";
}
}This defines CONSTANT on MyClass. A class constant is not the same as a global constant created with define(): const belongs to the class and is reached through ::, while define() registers a name in the global scope.
The value can be a constant expression — a calculation PHP can resolve at compile time — and even an array:
<?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"; // cmWhat you may not use is anything that is only known at runtime — function calls, object instances, or $variables are not allowed in a constant's value.
Accessing a class constant
How you read a constant depends on where you are:
- From outside the class, use the class name:
MyClass::CONSTANT. - From inside the class, use the
selfkeyword:self::CONSTANT.
constant value
constant valueThe first line reads the constant statically through the class name — no object required. The second goes through an instance method that uses self::CONSTANT. Note that you access constants with ::, never with the -> object operator that you use for properties.
Controlling visibility
Since PHP 7.1, class constants accept the same visibility modifiers as properties and methods: public (the default), protected, and private. This lets you hide implementation details that belong to the class but shouldn't be read from outside.
<?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 / x9f2Here Config::VERSION is accessible everywhere, while API_KEY and SALT can only be reached from inside the class (or, for protected, its subclasses). Trying to read Config::SALT from outside raises an error.
Constants and inheritance
Subclasses inherit their parent's constants and may override them. The keyword you use to read the constant decides which version you get:
self::NAMEis resolved when the code is written — it always means the constant in the class where the method is defined.static::NAMEis resolved at runtime against the actual class that was called. This is called late static binding.
<?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"; // activeInterfaces can declare constants too; they are implicitly public and shared by every implementing class. If you need a constant that subclasses must not override, mark it final (PHP 8.1+): final const ID = 100;. PHP 8.3 also added typed constants, e.g. const string LABEL = 'base';.
For more on subclassing behavior, see PHP Inheritance, and for the related class-level data feature, PHP Static Properties.
Common gotchas
- No dollar sign.
const RATE = 0.2;— writing$RATEis a syntax error. ::, not->. Constants are always reached with the scope-resolution operator.- Runtime values are rejected. A constant's value must be a constant expression;
const NOW = time();will not compile. selfvsstatic. Usestatic::when you intend a subclass to be able to override the value; otherwiseself::is the safer, more predictable choice.
Conclusion
Class constants give you named, immutable, class-scoped values defined with const and read through ::. Use them to centralize fixed values, improve readability, and lock down data that should never change at runtime. Combine them with visibility modifiers to hide internals, and remember the self vs static distinction once inheritance enters the picture.