PHP Reflection Real Application example sharing

Source: Internet
Author: User


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 
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.