Introduction
Even if the class member is defined as private, it can be accessed externally. Without creating an instance of the class, it can also access the class members and methods.
PHP has added a reflection mechanism since version 5.0. It provides a powerful reflection API, allowing you to access and use classes, methods, properties, parameters and comments in the PHP running environment. Its functions are very powerful. It is often used in the highly extended PHP framework, automatically load plug-ins, automatically generate documents, and can even be used to extend the PHP language. Since it is a built-in OOP extension in PHP and is a feature that comes with the language itself, it can be used without additional extensions or configurations. See more contentOfficial Documentation。
Reflection type
The PHP reflection API maintains the corresponding reflection classes based on classes, methods, properties, parameters, etc., and has provided the corresponding calling API.
type | illustrate |
---|---|
Reflector | Reflector is an interface implemented by all exportable reflection classes (implementation) |
Reflection | Reflection class |
ReflectionClass | Reports information about a class |
ReflectionZendExtension | Report information about Zend extensions |
ReflectionExtension | Report information about PHP extensions |
ReflectionFunction | Reports information about a function |
ReflectionFunctionAbstract | The parent class of ReflectionFunction |
ReflectionMethod | Reported information about a method |
ReflectionObject | Reports the relevant information about an object |
ReflectionParameter | Retrieve the relevant information about the function or method parameters |
ReflectionProperty | Reports related information about the attributes of the class |
access
Suppose that a class User is defined, we first need to establish a reflective class instance of this class, and then based on this instance, we can access the properties or methods in the User. It can be obtained regardless of whether the member permission declaration defined in the class is public or not.
<?php namespace Extend; use ReflectionClass; use Exception; /** * User-related categories * Class User * @package Extend */ class User{ const ROLE = 'Students'; public $username = ''; private $password = ''; public function __construct($username, $password) { $this->username = $username; $this->password = $password; } /** * Get username * @return string */ public function getUsername() { return $this->username; } /** * Set username * @param string $username */ public function setUsername($username) { $this->username = $username; } /** * Get password * @return string */ private function getPassword() { return $this->password; } /** * Set password * @param string $password */ private function setPassowrd($password) { $this->password = $password; } } $class = new ReflectionClass('Extend\User'); // Use the class name User as a parameter to create the reflection class of the User class$properties = $class->getProperties(); // Get all properties of the User class and return the array of ReflectionProperty$property = $class->getProperty('password'); // Get the password property of the User class ReflectionProperty$methods = $class->getMethods(); // Get all methods of the User class and return the ReflectionMethod array$method = $class->getMethod('getUsername'); // Get the ReflectionMethod of the getUsername method of the User class$constants = $class->getConstants(); // Get all constants and return the constant definition array$constant = $class->getConstant('ROLE'); // Get ROLE constant$namespace = $class->getNamespaceName(); // Get the namespace of the class$comment_class = $class->getDocComment(); // Get the comment document of the User class, that is, the comments defined before the class$comment_method = $class->getMethod('getUsername')->getDocComment(); // GetUserIn classgetUsernameMethod comment documentation
Note: The class name transmitted when creating a reflective class must contain the full namespace, even if the use keyword is used. Otherwise, an exception will be thrown if the class name is not found.
Interaction
Once an instance of the reflective class is created, we can not only access the methods and properties of the original class through the reflective class, but also create instances of the original class or directly call the methods in the class.
$class = new ReflectionClass('Extend\User'); // Use the class name User as a parameter to create the reflection class of the User class$instance = $class->newInstance('youyou', 1, '***'); // Create an instance of the User class $instance->setUsername('youyou_2'); // Call the instance of the User class to call the setUsername method to set the user name$value = $instance->getUsername(); // Use the instance of the User class to call the getUsername method to get the user nameecho $value;echo "\n"; // Output youyou_2 $class->getProperty('username')->setValue($instance, 'youyou_3'); // Set the username property value of the specified instance through the reflection class ReflectionProperty$value = $class->getProperty('username')->getValue($instance); // Get the username property value through the reflection class ReflectionPropertyecho $value;echo "\n"; // Output youyou_3 $class->getMethod('setUsername')->invoke($instance, 'youyou_4'); // Call the method of the specified instance through the reflection class ReflectionMethod and transfer parameters$value = $class->getMethod('getUsername')->invoke($instance); // Call the method of the specified instance through the reflection class ReflectionMethodecho $value;echo "\n"; // Output youyou_4 try { $property = $class->getProperty('password_1'); $property->setAccessible(true); // Modify the accessibility of the $property object $property->setValue($instance, 'password_2'); // Can be executed $value = $property->getValue($instance); // Can be executed echo $value;echo "\n"; // Output password_2 $class->getProperty('password')->setAccessible(true); // Modify the accessibility of temporary ReflectionProperty objects $class->getProperty('password')->setValue($instance, 'password');// Cannot execute, throw an exception that cannot be accessed $value = $class->getProperty('password')->getValue($instance); // Cannot execute, throw an exception that cannot be accessed $value = $instance->password; // Cannot be executed, the attributes of the class itself have not been modified, and it is still private}catch(Exception $e){echo $e;}
Things to note
- Direct access to protected or private familiarity or method will throw exceptions
- You need to call the specified ReflectionProperty or the ReflectionMethod object setAccessible(true) method to access non-public members.
- Modify non-public members' access rights to only the current reflective class instance
- It is necessary to note that the methods used to obtain static members and non-static members are different.
- The method of obtaining parent class members is different from the general one
If you have time, you will sort out the reflection class API table. You can check the detailed API list first.Official Documentation。
This is the end of this article about the case explanation of PHP reflection mechanism. For more related content of PHP reflection mechanism, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!