PHP constants name process-invariant scalar or array values through top-level const declarations, runtime define calls, namespaced symbols, class constants, predefined constants, and compile-time magic constants.
Good constant design places each value with its narrowest owner, uses enums for closed domain choices, keeps runtime configuration injectable, relies on symbolic flags, labels version-specific syntax, and migrates persisted identifiers before refactoring names.
| Feature | const | define() |
|---|---|---|
| Declared | Language syntax | Function call |
| Typical location | File or class declaration | Runtime bootstrap logic |
| Class constant | Yes | No |
| Dynamic name | No | Yes |
<?php
const MAX_LOGIN_ATTEMPTS = 5;
define('APP_ENV', 'development');
echo APP_ENV . ': ' . MAX_LOGIN_ATTEMPTS;
development: 5
A class constant belongs to a class or interface and is accessed with ::. Use it for values that define the public vocabulary of that type.
<?php
final class OrderStatus
{
public const PENDING = 'pending';
public const PAID = 'paid';
}
echo OrderStatus::PAID;
paid
Magic constants change according to where PHP reads them. __DIR__ and __FILE__ are especially useful for paths and diagnostics because they do not depend on the process working directory.
| Constant | Value |
|---|---|
| __DIR__ | Directory containing the current file |
| __FILE__ | Full path of the current file |
| __LINE__ | Current source line |
| __CLASS__ | Current class name |
| __METHOD__ | Current class method name |
| __NAMESPACE__ | Current namespace name |
Class constants group values with the type that owns their meaning and support visibility. Use enum cases when the value represents a closed domain choice with behavior, not a loose bag of strings. Avoid global constants for values that belong to one service or feature.
Constant names resolve through namespace rules, and dynamic constant access is harder to analyze. Do not place credentials in constants committed to source control. A constant prevents reassignment in PHP code; it does not make an array or external resource a security boundary.
A constant gives a name to a scalar or array value that cannot be redefined or unset during the script. It has no dollar sign, is case-sensitive in current PHP, and should communicate a value that is genuinely invariant for that process.
Use a variable, constructor argument, or configuration object for values that differ by request, tenant, user, test, or runtime decision. Calling changeable configuration a constant hides ownership and makes tests depend on process-global state.
An undefined constant raises an Error in PHP 8. Quote string keys and text deliberately; do not depend on the old bare-word fallback from earlier PHP releases. Use `defined()` when optional extension or deployment constants are expected.
Global constants ignore variable scope and can collide across libraries. Prefer a namespaced constant or a class/enum-owned constant when the value belongs to a domain type rather than the whole process.
`const` is a declaration and is normally the clearest choice for source-defined constants. A global const declaration belongs at top-level scope; it cannot be conditionally declared inside a function, loop, or try block.
`define()` creates a named constant at runtime and can use a dynamically calculated name. Dynamic names are rarely desirable in application design because static analysis and refactoring cannot see them clearly. Use the function when runtime declaration is truly part of the integration contract.
Both forms can define scalar values and arrays under current PHP rules. Avoid resources and mutable objects as constant-like global state. An array constant cannot be reassigned, while objects reached through other constant mechanisms may still have mutable behavior depending on the feature used.
Do not guard repeated application definitions with `if (!defined(...))` merely to tolerate uncertain bootstrap order. Give one file ownership of each declaration and load it predictably; conditional definitions can conceal conflicting environments.
A namespaced constant has a qualified identity just like other namespaced symbols. Unqualified lookup inside a namespace can fall back to a global constant under PHP resolution rules, which can hide a missing local declaration.
Use explicit imports or qualified names when ownership matters, especially for library APIs. Avoid giving a local and global constant the same short name because readers cannot infer which fallback is intended.
`constant($name)` retrieves a constant when the name is known only at runtime and works with class constants and enum cases too. Validate the external discriminator against an allowlist before converting it to a constant name; do not expose arbitrary symbol lookup.
`get_defined_constants()` is a diagnostic inventory, not a configuration API. It includes engine and extension values and can reveal environment details. Keep its output out of public responses.
A class constant belongs to a class or interface and is accessed with `::`. It can describe protocol names, fixed limits, or discriminators owned by that abstraction without creating an instance.
Visibility can make class constants public, protected, or private. Public values become part of the consumer contract; protected values support an inheritance surface; private values remain implementation detail. Changing an exposed value can still be a breaking behavioral change.
Inheritance and `self::` versus `static::` affect constant lookup. `self::` binds to the declaring class, while `static::` can use late static binding. Choose whether subclasses may specialize the value and test the consumer through the supported type.
Typed class constants are available on supported modern PHP versions and make the declared value category explicit. Version-label such syntax when a project supports older runtimes, and preserve compatible visibility and type in inheritance.
Use an enum case when the value represents one member of a closed domain set and callers need type-safe comparison or behavior. Use a class constant when the value is fixed metadata or a limit rather than an instance of the domain type.
Backed enum cases expose a scalar transport value, but the case identity remains the domain value. Parse external input with the enum conversion APIs and handle an unknown value instead of comparing raw strings throughout the application.
An interface constant is inherited by implementers and can create collisions or coupling when several interfaces use the same name. Prefer a dedicated enum or value type when consumers should depend on a shared concept rather than a convenience number.
Do not use a group of unrelated integer constants as a substitute for a sum type when invalid combinations are possible. Model bit flags only when combinations are meaningful and document the bitwise operations explicitly.
PHP core and loaded extensions provide predefined constants for versions, platforms, errors, filters, JSON behavior, paths, and other APIs. Availability can depend on the runtime build and loaded extension, so deployment checks should verify every required capability.
Use symbolic bitmask constants such as error or JSON flags instead of copied numeric values. Numeric values can change across PHP versions, while the symbolic name communicates intent and tracks the runtime definition.
`PHP_VERSION_ID` supports numeric version comparisons without parsing a display string, but feature detection is often stronger for extension functions, classes, or constants. Keep the application minimum version in deployment policy rather than scattering compatibility branches.
Platform constants such as directory and path separators describe process behavior. Prefer APIs that already accept portable paths, and test filesystem code on each supported operating system instead of assuming one separator solves every path rule.
Magic constants are compile-time contextual values. `__FILE__`, `__DIR__`, and `__LINE__` identify source location; `__FUNCTION__`, `__METHOD__`, `__CLASS__`, `__TRAIT__`, and `__NAMESPACE__` describe the declaration context; `ClassName::class` yields a qualified class-name string.
`__FILE__` and `__DIR__` refer to the file where they are written, including an included file. This makes `__DIR__` a dependable anchor for owned resources, while it should not be exposed in public error pages because it reveals server layout.
`ClassName::class` does not prove that the class exists or load it merely to create the string. It is useful for registrations and type discriminators, but persistent data should prefer a stable domain identifier if class names may change during refactoring.
On current PHP versions, `__PROPERTY__` is meaningful inside a property hook. Mark that coverage as version-specific and keep older-runtime code parseable. Magic values aid diagnostics and metaprogramming but should not replace explicit business identifiers.
Test constant values where they define a public protocol, limit, or mapping. Avoid tests that merely repeat the source literal; instead verify the behavior that depends on the value and add compatibility fixtures for external formats.
Static analysis can find undefined constants, invalid access visibility, incompatible inheritance, and dead declarations. Search configuration and deployment files too, because constants consumed through dynamic strings may evade normal symbol references.
A value that developers routinely override in tests is probably a dependency or configuration value, not a constant. Replace it with an injected clock, policy, limit object, or environment adapter so tests do not require isolated processes.
During migrations, search persisted class names, serialized payloads, cache keys, and bitmask values before renaming public constants. Release mixed-version producers and consumers only when both understand the transition representation.
Try this next
0 of 2 completed
Explore 500+ free tutorials across 20+ languages and frameworks.