PHP动态访问self::类常量:如何通过变量名调用类常量
Hey Chris, great question! The issue with your current self::$id approach is that PHP doesn’t support directly using a variable to reference a class constant like that—we need a small adjustment to make this work. Let’s walk through two solid solutions tailored to your Dimensions enum class.
Solution 1: Use PHP’s constant() Function
The simplest fix is to build the full qualified constant name (class + constant identifier) and use PHP’s built-in constant() function to fetch its value. This is clean and requires minimal code changes:
class Dimensions extends Enum { const U_1 = ['xxx' => 'A']; const U_2 = ['xxx' => 'B']; static function all() { $oClass = new ReflectionClass(__CLASS__); return $oClass->getConstants(); } static function byId(string $id) { // Construct the full path to the constant $constantFullName = __CLASS__ . '::' . $id; // Validate the constant exists to avoid fatal errors if (!defined($constantFullName)) { throw new InvalidArgumentException("Constant '$id' doesn't exist in the " . __CLASS__ . " class"); } return constant($constantFullName); } }
Solution 2: Reuse Reflection (Leverage Your Existing all() Method)
Since your all() method already uses ReflectionClass to fetch all constants, you can reuse that logic in byId() too. This is handy if you want to avoid repeating class name references or need to work with the full set of constants for extra logic:
class Dimensions extends Enum { const U_1 = ['xxx' => 'A']; const U_2 = ['xxx' => 'B']; static function all() { $oClass = new ReflectionClass(__CLASS__); return $oClass->getConstants(); } static function byId(string $id) { $constants = self::all(); // Check if the requested constant exists if (!isset($constants[$id])) { throw new InvalidArgumentException("Constant '$id' doesn't exist in the " . __CLASS__ . " class"); } return $constants[$id]; } }
Quick Tips
- Always validate existence: Adding the check for the constant’s presence prevents unexpected fatal errors if someone passes an invalid
$id. You can adjust this to returnnullor a default value instead of throwing an exception if that fits your use case better. - Native Enum note: If you’re using PHP 8.1+ native
Enuminstead of a custom enum pattern, built-in methods liketryFrom()might simplify this workflow—but your constant-based approach works perfectly for older PHP versions or custom enum structures.
内容的提问来源于stack exchange,提问作者Chris

