PHP反射機制從PHP5開始支持,作業務開發的話應該不多接觸反射。我其實也是接觸很少,最近在學習laravel的"優雅",就接觸了到它其中的反射用法,已經我本身的見解想法。php
按照以前的套路,咱們來看一下官方手冊,官方是怎麼說的。laravel
PHP 5 具備完整的反射 API,添加了對類、接口、函數、方法和擴展進行反向工程的能力。 此外,反射 API 提供了方法來取出函數、類和方法中的文檔註釋。個人理解就是php反射機制能拿到類裏面的屬性方法,private 和 protected的也能夠閉包
laravel整個框架設計的"優雅"就是在於container、IOC、依賴注入。咱們來看一下容器中一段關於反射的代碼:
IlluminateContainerContainer:架構
/** * Instantiate a concrete instance of the given type. * * @param string $concrete * @param array $parameters * @return mixed * * @throws \Illuminate\Contracts\Container\BindingResolutionException */ public function build($concrete, array $parameters = []) { // If the concrete type is actually a Closure, we will just execute it and // hand back the results of the functions, which allows functions to be // used as resolvers for more fine-tuned resolution of these objects. if ($concrete instanceof Closure) { return $concrete($this, $parameters); } $reflector = new ReflectionClass($concrete); // If the type is not instantiable, the developer is attempting to resolve // an abstract type such as an Interface of Abstract Class and there is // no binding registered for the abstractions so we need to bail out. if (! $reflector->isInstantiable()) { if (! empty($this->buildStack)) { $previous = implode(', ', $this->buildStack); $message = "Target [$concrete] is not instantiable while building [$previous]."; } else { $message = "Target [$concrete] is not instantiable."; } throw new BindingResolutionException($message); } $this->buildStack[] = $concrete; $constructor = $reflector->getConstructor(); // If there are no constructors, that means there are no dependencies then // we can just resolve the instances of the objects right away, without // resolving any other types or dependencies out of these containers. if (is_null($constructor)) { array_pop($this->buildStack); return new $concrete; } $dependencies = $constructor->getParameters(); // Once we have all the constructor's parameters we can create each of the // dependency instances and then use the reflection instances to make a // new instance of this class, injecting the created dependencies in. $parameters = $this->keyParametersByArgument( $dependencies, $parameters ); $instances = $this->getDependencies( $dependencies, $parameters ); array_pop($this->buildStack); return $reflector->newInstanceArgs($instances); }
就是實現綁定類的方法,build方法。下面咱們就來分析一下:框架
其實在上面這個laravel中的例子已經很好的闡明瞭反射機制的使用方式,或許你如今的業務場景還未必可以使用到這種機制。可是,當碰到的時候請記得還有這種方式可以使用。函數
$class = new ReflectionClass(ucfirst($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!"); }
$class = new ReflectionClass($class); if ($class->hasMethod($method)) { $method = $class->getMethod($method); $object = $class->newInstance(); $class = $method->invokeArgs(new $object, $params); var_dump($res === $assert); }
還有不少好玩的等着你本身去嘗試,這種機制究竟能玩出多少花樣,就看你本身怎麼玩了。單元測試