PHP Class Constants

Keep fixed values with their owning class, control access and understand self versus static lookup.

Lesson 47 of 86Advanced10 min read

A class constant attaches a fixed value to a class. Product::MAX_STOCK says both what the value means and which component owns it. That can be clearer than a global MAX_STOCK name, especially when several parts of an application have different limits. Constants use double-colon access and are not per-object mutable properties.

This reference covers declaration, visibility, inheritance and the difference between self and static. It also explains final and typed class constants with their minimum PHP versions. You will build a small format class and decide which values belong in its public contract and which should remain internal.

Declare values at the class level

Use const NAME = value; inside a class. A constant can hold a scalar or an array in modern PHP. Read it with ClassName::NAME, and inside the class often with self::NAME. There is no dollar sign before a constant name and no assignment to it after declaration.

Choose names describing stable rules or formats, such as DEFAULT_SEPARATOR or MAX_LABEL_LENGTH. A changing order total belongs in an instance property, not a constant. A runtime environment setting may belong in injected configuration rather than a fixed class declaration. Class ownership should add meaning, not merely provide a container for unrelated numbers.

Use a constant when callers should rely on a fixed named value. If callers should ask an object for a policy that can vary by deployment or user, a method and dependency can be more flexible. Public constants become part of the component's API, so changing them may affect consumers even when no method signature changes.

Visibility protects the intended interface

Class constant visibility has been available since PHP 7.1. Public constants can be accessed by callers. Protected constants are available within the class hierarchy. Private constants belong to the declaring class's internal implementation. If visibility is omitted, a class constant is public.

Use private for an implementation detail callers should not depend on. Use protected only when child implementations have a meaningful need for the value. Public suits a stable external format code or documented limit. Visibility is a communication and encapsulation tool, not a mechanism for keeping secrets confidential from the application process.

A private constant can still contain a credential, but that does not make storing the credential in source safe. Load secrets through a controlled deployment configuration path. Choose visibility based on the class interface and secret handling based on the storage and exposure boundary.

Inheritance, self and static

A child inherits accessible class constants and can redeclare a nonfinal inherited constant. self::NAME is resolved from the class where that code is written. static::NAME uses late static binding and can resolve to the called child class's value. This allows a shared method to respect a subclass configuration deliberately.

Use self when the method must rely on the declaring class's fixed implementation rule. Use static when the value is an intended extension point. The choice should follow the design, not a habit of replacing every self with static. A child-specific value can violate a base invariant if the base was never designed for variation.

Keep visibility and override rules in mind. A protected constant can be used by a child, but a private one is not a general extension hook. If consumers must not alter a constant through inheritance, final provides an explicit restriction in supported PHP versions.

Final and typed constants need version checks

PHP 8.1 added final class constants, which a child cannot override. They can preserve a documented protocol value or another rule that must remain consistent through inheritance. Final should protect a real invariant; overusing it can block legitimate specialization without improving correctness.

PHP 8.3 added typed class constants, allowing declarations such as public const int MAX_ITEMS = 20;. The type constrains the declared value and participates in inheritance rules. Untyped constants remain useful for projects supporting older versions. Do not add syntax that your minimum runtime cannot parse.

The PHP class constants manual documents visibility, final constants, typed constants and dynamic access additions. Keep Composer's platform requirements and deployment workers aligned with the syntax you use. A newer local CLI does not prove older production workers can load the same source.

PHP Class Constants Examples

Each example shows the code, the output it produces and what each part does.

Example 1

Read a class-owned limit

The public limit is accessible outside the class. The private prefix is read only from the class's own code. The display method does not enforce the limit in this small example; a complete label object would validate or shorten input according to an explicit policy rather than assuming the constant does that work.

PHP
<?php
class Label {
    public const MAX_LENGTH = 40;
    private const PREFIX = 'Item: ';

    public function display(string $name): string {
        return self::PREFIX . $name;
    }
}
echo Label::MAX_LENGTH . PHP_EOL;
echo (new Label())->display('Pen') . PHP_EOL;
Output
40
Item: Pen
Example 2

Observe class-specific lookup

The method is written in BaseFormat, so self reads base. The call uses CompactFormat, so static respects the child. This is the same late-binding principle used for static methods, but the values themselves remain immutable constants.

PHP
<?php
class BaseFormat {
    public const NAME = 'base';
    public static function names(): string {
        return self::NAME . ':' . static::NAME;
    }
}
class CompactFormat extends BaseFormat {
    public const NAME = 'compact';
}
echo CompactFormat::names() . PHP_EOL;
Output
base:compact

Common PHP Class Constants Mistakes

Confusing constants with static properties

ClassName::VALUE accesses a constant. ClassName::$value accesses a static property. The property can normally change, while the constant cannot. If the application needs a changing counter or cache, a constant is the wrong storage. If it needs a stable format code, a mutable static property weakens the guarantee unnecessarily.

Do not make every constant public just to simplify testing. Tests should usually verify observable behavior and documented contracts, not force internal values into the public API. Use meaningful assertions about results and preserve the class's ownership boundaries.

PHP Class Constants in Real Projects

Practical task: own a serialization separator

Create a small serializer class with a private separator and a public format name. The separator is an implementation detail of this example, while callers can use the public name in diagnostics. Join a trusted list of labels and print the format name alongside the result.

PHP
<?php
class LabelSerializer {
    public const FORMAT = 'pipe-labels';
    private const SEPARATOR = '|';

    public function encode(array $labels): string {
        return implode(self::SEPARATOR, $labels);
    }
}
$serializer = new LabelSerializer();
echo LabelSerializer::FORMAT . PHP_EOL;
echo $serializer->encode(['Pen', 'Book']) . PHP_EOL;
Output
pipe-labels
Pen|Book

The method assumes labels do not contain the separator. For a true interchange format, define escaping or use a standard format such as JSON or CSV instead. A constant makes a delimiter consistent but does not design a robust parser. Try a label containing a pipe and explain why the simple representation becomes ambiguous.

PHP Class Constants FAQ

Can an object read a class constant?

Class constants belong to the class and are normally accessed with class syntax. Their value does not vary per instance.

Can a class constant be an array?

Yes in modern PHP. The array value cannot be edited as a mutable property.

Is a private constant encrypted?

No. Private limits code-level access; it is not secure secret storage.

Which lookup follows the child class?

Static uses late static binding. Self uses the class where the method is declared.

When should I use an enum instead?

Use an enum when a parameter should accept only a fixed set of typed choices. Constants provide named values without that same case-type contract.

PHP Class Constants Exercises

Answer each one and check it instantly. If you get stuck, open the hint before the answer.

Multiple choiceeasy

A delimiter is an internal implementation detail. Which visibility is most appropriate by default?

PHP Class Constants Quiz

2 questions to check what you learned.

  1. Which syntax reads a class constant?

    • Product::$MAX_STOCK
    • Product::MAX_STOCK
    • $Product.MAX_STOCK
  2. Which lookup can respect an overriding child constant in an inherited static method?

    • self::NAME always
    • global NAME
    • static::NAME