This article mainly share with you the actual application of PHP reflection, based on the reflection of the analysis of classes, interfaces, functions and methods of the internal structure, methods and functions of the parameters, as well as the properties and methods of the class, can be automatically generated documents.
<?phpclass student{Const NORMAL = 1; Const FORBIDDEN = 2; /** * User ID * @var type */public $id; /** * Get ID * @return int */Public Function getId () {return $this->id; The Public function setId ($id = 1) {$this->id = $id; }} $ref = new Reflectionclass (' Student '); $doc = $ref->getdoccomment (); Echo $ref->getname (). ':' . Getcomment ($ref), "<br/>"; Echo "Property list:<br/>";p rintf ("%-15s%-10s%-40s<br/>", ' Name ', ' Access ', ' Comment '), $attr = $ref->getproperties (), foreach ($attr as $row) {printf ("%-15s%-10s%-40s<br/>", $row->get Name (), getaccess ($row), Getcomment ($row));} echo "Constant list:<br/>";p rintf ("%-15s%-10s<br/>", ' Name ', ' Value '), $const = $ref->getconstants (); foreach ($ Const as $key = = $val) {printf ("%-15s%-10s<br/>", $key, $val);} echo "<br/><br/>", echo "method list <br/>";p rintf ("%-15s%-10s%-30s%-40s<br/>", ' Name ', ' Access ', ' Params ', ' Comment '), $methods = $ref->getmethods (), foreach ($methods as $row) {printf ("%-15s%-10s%-30s%-40s<br/>", $row-&G T;getname (), getaccess ($row), Getparams ($row), Getcomment ($row));} Get Permission function getaccess ($method) {if ($method->ispublic ()) {return ' public '; } if ($method->isprotected ()) {return ' Protected '; } if ($method->isprivate ()) {return ' Private '; }}//Get method parameter information function Getparams ($method) {$str = '; $parameters = $method->getparameters (); foreach ($parameters as $row) {$str. = $row->getname (). ','; if ($row->isdefaultvalueavailable ()) {$str. = "Default: {$row->getdefaultvalue ()}"; }} return $str? $str: ';} Gets the comment function getcomment ($var) {$comment = $var->getdoccomment (); Simply get the first line of information, where you can expand Preg_match ('/\* (. *) *?/', $comment, $res); return Isset ($res [1])? $res [1]: ';}
Output Result:
Student: Attribute list: Name access Comment ID Public User ID constant list: name Value NORMAL 1 FORBIDDEN 2 Method list name Access Params Comment getId Public get ID setId public id,default:1
2. Implementing the MVC Architecture
Many frameworks are now the MVC architecture that locates the names of controllers ($controller) and Methods ($method) based on routing information, and then uses reflection to implement automatic calls.
$class = new Reflectionclass (Ucfirst ($controller). ' Controller '); $controller = $class->newinstance (); if ($class->hasmethod ($method)) { $method = $class GetMethod ($method); $method->invokeargs ($controller, $arguments);} else { throw new Exception ("{$controller} Controller method {$method} not exists!");}
3. Implementing unit Tests
In general, we test the functions and classes to see if they can return the results as we expect, and we can implement a simple generic class test case with reflection.
<?phpclass calc{public function plus ($a, $b) { return $a + $b; } Public function minus ($a, $b) { return $a-$b; }} function testequal ($method, $assert, $data) { $arr = explode (' @ ', $method); $class = $arr [0]; $method = $arr [1]; $ref = new Reflectionclass ($class); if ($ref->hasmethod ($method)) { $method = $ref->getmethod ($method); $res = $method->invokeargs (new $class, $data); if ($res = = = $assert) { echo "test result is correct";} ;} } Testequal (' Calc@plus ', 3, [1, 2]); Echo "<br/>"; testequal (' Calc@minus ',-1, [1, 2]);
This is a test method for a class, and you can also use reflection to implement a function's test method.
<?phpfunction title ($title, $name) { return sprintf ("%s.%s\r\n", $title, $name);} $function = new Reflectionfunction (' title '), Echo $function->invokeargs (' Dr ', ' Phil ');? >
Here is just a test case that I write briefly, PHPUnit unit testing framework relies heavily on the Reflection characteristics, can be understood.
4. Work with DI containers to resolve dependencies
Many frameworks, such as Laravel, use Reflection to solve dependency injection problems, and see Laravel Source for analysis.
The following is a simple implementation of a DI container demonstrating Reflection solving dependency injection problems.
<?phpclass di{protected static $data = []; Public Function __set ($k, $v) {self:: $data [$k] = $v; The Public Function __get ($k) {return $this->bulid (self:: $data [$k]); }//Get instance Public function Bulid ($className) {//If it is an anonymous function, execute directly and return the result if ($className instanceof Closu RE) {return $className ($this); }//is already an instantiated object, return directly if (Is_object ($className)) {return $className; }//If it is a class, use reflection to load $ref = new Reflectionclass ($className); The monitoring class can instantiate if (! $ref->isinstantiable ()) {throw new Exception (' class ' $className. ' Not find '); }//Get constructor $construtor = $ref->getconstructor (); No constructors, direct instantiation returns if (Is_null ($construtor)) {return new $className; }//Get constructor parameters $params = $construtor->getparameters (); Parse constructor $dependencies = $this->getdependecies ($params); Create a new instance return $ref->newinstanceargs ($dependencies); }//Parse parameters, if a dependent class appears in the parameter, recursively instantiate public function getdependecies ($params) {$data = []; foreach ($params as $param) {$tmp = $param->getclass (); if (Is_null ($tmp)) {$data [] = $this->setdefault ($param); } else {$data [] = $this->bulid ($tmp->name); }} return $data; }//Set default public function SetDefault ($param) {if ($param->isdefaultvalueavailable ()) {RET Urn $param->getdefaultvalue (); } throw new Exception (' no default value! '); }}class demo{Public Function __construct (Calc $calc) {echo $calc->plus (1, 2); }}class calc{public Function plus ($a, $b) {return $a + $b; The public function minus ($a, $b) {return $a-$b; }} $di = new Di (); $di->calc = ' calc '; $di->demo = ' demo '; $di->demo;//output result is 3