前言PHP的反射类与实例化对象是相对的。实例化是调用封装类中的方法和成员,而反射类是将类中的所有方法和成员变量解包。并包括私有方法等。就像“解剖”一样,我们可以调用任何关键字修饰的方法和成员。当然,建议不要在正常业务中使用。与反射类相比,封装的概念已经被摒弃。本章讲解反射类的使用和Laravel对反射的使用。反射反射类是PHP内部类,无需加载即可使用。您可以通过实例化ReflectionClass类来使用它。方法以下是PHP反射类中常用的方法。方法名称注解ReflectionClass::getConstant获取定义的常量getDocComment获取文档注释ReflectionClass::getEndLine获取最后一行的行号ReflectionClass::getFileName获取定义类的文件名符号ReflectionClass::getName获取类名ReflectionClass::getNamespaceName获取命名空间的名称ReflectionClass::getParentClass获取父类等等...所有方法、属性及其继承的父类和类的实现接口都可以找到。详细文档请参考官网:http://php.net/manual/zh/clas...栗子inNamespace());var_dump($function->getName());var_dump($function->getNamespaceName());var_dump($function->getShortName());$function=new\ReflectionClass('A\\B\\Foo');var_dump($function->inNamespace());var_dump($function->getName());var_dump($function->getNamespaceName());var_dump($function->getShortName());?>输出bool(false)string(8)"stdClass"string(0)""string(8)"stdClass"bool(true)string(7)"A\B\Foo"string(3)"A\B"string(3)"Foo"LaravelLaravel在实现服务容器加载时使用了反射类。现在我们打开“刨”模式入口文件index.php$app=require_once__DIR__.'/../bootstrap/app.php';/*|--------------------------------------------------------------------|运行应用程序|--------------------------------------------------------------------------||一旦有了应用程序,我们就可以处理传入的请求|通过内核,并将关联的响应发送回|客户的浏览器让他们享受创意|以及我们为他们准备的精彩应用程序。::capture());$response->send();$kernel->terminate($request,$response);是quote语句出现的下一行调用make方法。大家都很清楚make方法是用来解析类的,所有make方法的实现都必须在引用的文件中。bootstrap\app.php$app=newIlluminate\Foundation\Application(realpath(__DIR__.'/../'));laravel开始加载它的核心类,所有的实现都从Illuminate\Foundation\Application开始。Illuminate\Foundation\Applicationpublicfunctionmake($abstract,array$parameters=[]){$abstract=$this->getAlias($abstract);}如果(isset($this->deferredServices[$abstract])&&!isset($this->instances[$abstract])){$this->loadDeferredProvider($abstract);}returnparent::make($abstract,$parameters);}在核心类中,你可能会发现make方法正是存在的,它加载服务提供者然后调用父类的make方法。要知道,作为一个独立模块的“服务容器”是绝对不能写在核心类中的。懂设计模式的都非常清楚。Illuminate\Container\Container使用$api=$this->app->make('HelpSpot\API',['id'=>1]);举例说明//真正的make方法,直接调用resolve继续实现make的功能//$abstract='HelpSpot\API'publicfunctionmake($abstract,array$parameters=[]){//$abstract='HelpSpot\API'return$this->resolve($abstract,$parameters);}...protectedfunctionresolve($abstract,$parameters=[]){...//判断反射是否合理//$abstract='HelpSpot\API'if($this->isBuildable($concrete,$abstract)){//实例化一个具体实例(实际上不是实例化,而是通过反射“剖析”)$object=$这个->构建($混凝土);}else{$object=$this->make($concrete);}...}publicfunctionbuild($concrete){//$concrete='HelpSpot\API'if($concreteinstanceofClosure){return$concrete($this,$this->getLastParameterOverride());}//实例化反射类$reflector=newReflectionClass($concrete);//检查类是否可以被实例化if(!$reflector->isInstantiable()){返回$this->notInstantiable($concrete);}$this->buildStack[]=$concrete;//获取类构造函数$constructor=$reflector->getConstructor();如果(is_null($constructor)){array_pop($this->buildStack);返回新的$混凝土;}$dependencies=$constructor->getParameters();$instances=$this->resolveDependencies($dependencies);array_pop($this->buildStack);//根据给定的参数创建一个新的类实例return$reflector->newInstanceArgs($instances);}可以看出一个服务容器加载成功。谢谢您阅读此篇。本文源码分析靠个人理解。如有不妥,请拍砖。希望这篇文章能帮到你。谢谢
