We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
PHP's reflection capabilities are powerful tools that allow you to inspect and manipulate class information at runtime. One handy use case is fetching class constants dynamically. However, if you're working with inheritance, you may want to filter out constants that come from a parent class and focus only on those declared in the child class.
In this post, we'll go through how to achieve this using PHP's ReflectionClass
.
Why use Reflection to get constants?
While it's easy to declare constants in PHP, there are situations where you need to fetch all constants of a class dynamically. For instance, when working with a list of predefined privileges or settings (constants), you might want to get them in an array for processing or validation.
Here's a simple example of a class with constants:
class Setting extends Model
{
public const MANAGE_USERS = 'manage.users';
public const MANAGE_TEAMS = 'manage.teams';
}
In the above Setting
class, we define several constants related to various system settings. Using reflection, we can
fetch these constants dynamically at runtime and return them as an associative array.
Using Reflection to get class constants
PHP's ReflectionClass
provides an easy way to retrieve class information, including constants. Here's how to create a
method to fetch all constants of a class:
public static function getConstants(): array
{
$reflection = new \ReflectionClass(self::class);
return $reflection->getConstants();
}
How it works
ReflectionClass(self::class)
: Creates a reflection of the class where the method is called.getConstants()
: Returns an associative array where the keys are constant names and the values are the constant values.
You can use this method to get all constants like so:
$constants = Setting::getConstants();
print_r($constants);
This will output:
Array
(
[MANAGE_USERS] => manage.users
[MANAGE_TEAMS] => manage.teams
[CREATED_AT] => created_at
[UPDATED_AT] => updated_at
)
As you might notice, the constants also include all the ones inherited from the parent class.
Handling inherited constants
If the class extends a base class (like Model in our example), some constants might be inherited from the parent class. Often, you'll want to filter these out and only work with constants declared in the current class. This can be done by comparing the constants of the child class with those of the parent class.
Filtering Out Inherited Constants
Here's the updated method that filters out constants inherited from the parent class:
public static function getConstants(): array
{
$reflection = new \ReflectionClass(self::class);
$parentClass = $reflection->getParentClass();
// Get constants of the current class
$childConstants = $reflection->getConstants();
// Get constants of the parent class, if any
$parentConstants = $parentClass !== false ? $parentClass->getConstants() : [];
// Filter out constants inherited from the parent class
return array_diff_assoc($childConstants, $parentConstants);
}
Explanation
- Reflection of
self::class
: This fetches the constants declared in theSetting
class. getParentClass()
: This checks if the class has a parent and gets the parent class reflection object.array_diff_assoc()
: Compares the constants of the child class with those of the parent class and removes any that are the same (i.e., inherited).
Now, when you call Setting::getConstants()
, it will return only the constants declared in the Setting
class,
excluding those inherited from Model
:
$constants = Setting::getConstants();
print_r($constants);
This will give you:
Array
(
[MANAGE_USERS] => manage.users
[MANAGE_TEAMS] => manage.teams
)
Conclusion
Using PHP's reflection API, you can easily extract class constants and filter out inherited ones. This can be particularly useful when working with large codebases where constants are defined across multiple classes. By reflecting on the class and filtering with array_diff_assoc(), you ensure that you only get the constants you need from the child class.
This approach keeps your code dynamic and flexible, allowing you to handle constants without hardcoding any logic that depends on inheritance structures.
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts, subscribe use the RSS feed.