class-constants
constants for single standalone values, open sets, or configuration keys. - Restrict constant visibility to the narrowest scope — Declare private const or protected const (PHP 7.1+) for implementation detail constants; reserve public const for values that are part of the class contract.
Works with
Agent Skills format with YAML frontmatter. Claude Code reads it as-is.
--- name: "class-constants" description: "constants for single standalone values, open sets, or configuration keys. - Restrict constant visibility to the narrowest scope — Declare private const or protected const (PHP 7.1+) for implementation detail constants; reserve public const for values that are part of the class contract." license: "MIT" --- <!-- generated: do not edit — source: knowledge/atoms/php/class-constants/ --> <!-- schema: atomVersion=3 skillVersion=2 graphVersion=1 --> <!-- compile: @php-skills/compiler v1.0.0 (deterministic build) --> # Class Constants ## When to use - The user needs a named, compile-time constant value bound to a class or interface. - The user wants several classes to share the same constant values via an interface or base class. - The user needs a fixed set of named values but targets PHP 7.4 or 8.0 where enums do not exist. ## When NOT to use - Do not model a closed set of related values with class constants when the runtime is PHP 8.1+ and an enum would fit. - Do not use class constants for values that vary by environment or must change at runtime. ## Core guidance - **Prefer an enum for a closed set on PHP 8.1+** — On PHP 8.1+, use a backed enum for a closed set of related named values; keep class constants for single standalone values, open sets, or configuration keys. - **Restrict constant visibility to the narrowest scope** — Declare `private const` or `protected const` (PHP 7.1+) for implementation detail constants; reserve `public const` for values that are part of the class contract. ## Quick recipe 1. Declare the constant with an explicit visibility, e.g. `private const MAX_TRIES = 3;` (add a type on PHP 8.3, `private const int MAX_TRIES = 3;`). (verify: `ReflectionClassConstant` reports the expected visibility) 2. Reference the constant with `self::MAX_TRIES` for a fixed value, or `static::MAX_TRIES` when subclasses should be able to override it. (verify: A subclass override changes behavior only when `static::` is used) 3. If the constant is one of a closed related set and the runtime is PHP 8.1+, migrate the group to a backed enum instead of adding more constants. (verify: A closed set is expressed as an enum; standalone values remain constants) ## Best practices - Declare `final const` (PHP 8.1+) when a subclass must not redefine the value, so the constant is guaranteed stable across the hierarchy - Put constants that several implementers must share on an interface; implementing classes inherit them and cannot weaken the contract - Reference a constant with `self::NAME` to always resolve the defining class, and `static::NAME` when a subclass should be able to override the value (late static binding) - On PHP 8.3+, give constants an explicit type (`public const string ROLE = 'admin';`) so overrides in subclasses and interfaces must keep a compatible type ## Anti-patterns | Anti-pattern | Why it fails | Do instead | | --- | --- | --- | | A bag of constants where an enum belongs | Constants accept any scalar, so nothing stops an invalid value from flowing through the code. | Replace the group with a backed enum so the type system rejects values outside the set;<br>keep constants only for standalone or extensible values. | | Inline magic numbers instead of a named constant | Duplicated literals drift apart and hide meaning, so a change means hunting every copy. | Name the value once as a class constant (`const MAX_TRIES = 3;`) and reference it,<br>keeping a single source of truth. | | Leaving every constant public | Public constants become part of the API; callers depend on them and you can no longer change them freely. | Mark implementation detail constants `private const` or `protected const` (PHP 7.1+)<br>and expose only what is truly part of the contract. | See [references/anti-patterns.md](references/anti-patterns.md). ## Common mistakes 1. **Treating an array constant as immutable data** — An array class constant cannot be mutated in place, but code that copies it and edits the copy assumes changes stick — they do not affect the constant. Fix: Keep constants for truly fixed data; when callers need to build on it, expose a method that returns a fresh, explicitly-modified array. 2. **A self reference ignores a subclass override** — A method using `self::CONST` keeps the parent value even when a subclass redefines the constant. Fix: Use `static::CONST` when a subclass is meant to override the value (late static binding). 3. **Constant visibility modifiers need PHP 7.1+** — Writing `private const` or `protected const` on PHP 7.0 or earlier is a fatal parse error. Fix: On PHP 7.0, drop the modifier (constants are public) or upgrade the runtime. ## Version notes - **Constant visibility modifiers added in PHP 7.1** (PHP >=7.1) — `public`, `protected`, and `private` modifiers on class constants are available from PHP 7.1; earlier versions treat every constant as public. - **Final class constants added in PHP 8.1** (PHP >=8.1) — `final const` on class and interface constants is available from PHP 8.1, preventing subclasses or child interfaces from redefining the value. - **Typed class constants added in PHP 8.3** (PHP >=8.3) — From PHP 8.3, class, interface, and enum constants can declare a type; overrides must stay type-compatible with the parent declaration. ## Security - Not applicable — no I/O, auth, or untrusted input. ## Testing - Activation and decision behavior are verified in `eval/scenarios/php/class-constants.yaml`. ## Additional resources - [references/anti-patterns.md](references/anti-patterns.md) - [references/core.md](references/core.md) - [references/examples.md](references/examples.md) - [references/pitfalls.md](references/pitfalls.md) - [references/recipes.md](references/recipes.md) - [references/version-differences.md](references/version-differences.md) ## Knowledge graph **Related:** [bitrix/kernel-main-module](../../bitrix/kernel-main-module/SKILL.md), [php/enums](../../php/enums/SKILL.md), [php/value-objects](../../php/value-objects/SKILL.md) <!-- graph-fragment: graph/fragments/php/class-constants.yaml -->
More General & Other skills
find-skills
vercel-labs/skills
Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
grill-me
mattpocock/skills
A relentless interview to sharpen a plan or design.
grill-with-docs
mattpocock/skills
A relentless interview to sharpen a plan or design, which also creates docs (ADR's and glossary) as we go.

