PHP5 adds a new feature: Reflection. This feature allows programmers to reverse-engineer class, interface, function, method and extension. Through PHP code, you can get all the information of an object and interact with it.
Suppose there is a class Person:
class Person { /** * For the sake of demonstration, we"re setting this private */ private $_allowDynamicAttributes = false; /** type=primary_autoincrement */ protected $id = 0; /** type=varchar length=255 null */ protected $name; /** type=text null */ protected $biography; public function getId() { return $this->id; } public function setId($v) { $this->id = $v; } public function getName() { return $this->name; } public function setName($v) { $this->name = $v; } public function getBiography() { return $this->biography; } public function setBiography($v) { $this->biography = $v; } }
Through ReflectionClass, we can get the following information of the Person class:
Just pass the class name "Person" to ReflectionClass:
$class = new ReflectionClass('Person');
Get properties (Properties):
$properties = $class->getProperties(); foreach($properties as $property) { echo $property->getName()."n"; } // 输出: // _allowDynamicAttributes // id // name // biography
By default, ReflectionClass will get all properties, including private and protected ones. If you only want to get the private attribute, you need to pass an additional parameter:
$private_properties = $class->getProperties(ReflectionProperty::IS_PRIVATE);
Available parameter list:
If you want to get both public and private properties, write like this: ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED
It shouldn’t feel strange.
The property name can be obtained through $property->getName(), and the comment written to the property can be obtained through getDocComment.
foreach($properties as $property) { if($property->isProtected()) { $docblock = $property->getDocComment(); preg_match('/ type=([a-z_]*) /', $property->getDocComment(), $matches); echo $matches[1]."n"; } } // Output: // primary_autoincrement // varchar // text
It’s a bit incredible. You can even get comments.
Get methods: Get all methods of the class through getMethods(). What is returned is an array of ReflectionMethod objects. No more demonstrations.
Finally, call the method in the class through ReflectionMethod.
$data = array("id" => 1, "name" => "Chris", "biography" => "I am am a PHP developer"); foreach($data as $key => $value) { if(!$class->hasProperty($key)) { throw new Exception($key." is not a valid property"); } if(!$class->hasMethod("get".ucfirst($key))) { throw new Exception($key." is missing a getter"); } if(!$class->hasMethod("set".ucfirst($key))) { throw new Exception($key." is missing a setter"); } // Make a new object to interact with $object = new Person(); // Get the getter method and invoke it with the value in our data array $setter = $class->getMethod("set".ucfirst($key)); $ok = $setter->invoke($object, $value); // Get the setter method and invoke it $setter = $class->getMethod("get".ucfirst($key)); $objValue = $setter->invoke($object); // Now compare if($value == $objValue) { echo "Getter or Setter has modified the data.n"; } else { echo "Getter and Setter does not modify the data.n"; } }
Interesting.