laravel中的反射机制

反射机制被Ruby、PHP等多种语言广泛应用,主要用来动态地获取系统中类、实例对象、方法等语言构件的信息,通过反射API函数可以实现对这些语言构件信息的动态获取和动态操作等。PHP5具有完整的反射API,添加了对类、接口、函数、方法和扩展进行反向工作的能力。此外,反射API还提供了获取函数、类和方法等语言构件中的文档的注释方法。下面介绍一个具体实例。

通过上面的实例可以看到反射机制的强大,在很多情况下可以使得代码更加高效,例如事先不知道需要实例化哪个类,而是在运行时根据动态信息确定,对于这种情况可以通过反射机制获取需要实例化类的构造函数信息并完成相应的实例化。在Laravel框架中,服务容器解析服务的过程中就用到了反射机制。下面给出Laravel框架中解析服务的实例。文件:Illuminate\Container\Container.php

在Laravel框架中,解析服务是通过build()函数实现的,一般分为两种情况:一种是查找对应服务是否被服务提供者注册为实例或提供服务的匿名函数,如果是,则直接进行服务解析;第二种是服务名称没有相应的服务绑定,通过反射机制来动态创建服务。通过反射机制动态创建服务的过程可以分为两个步骤:第一步是通过反射机制获取服务类构造函数的信息,第二步是解决服务类构造函数的依赖问题。首先,通过“$reflector=newReflectionClass($concrete);”来创建一个反射类实例,其中$concrete是类的名称,然后通过“$reflector->isInstantiable();”判断这个类是否可以实例化,如果不可以则抛出异常,接着通过“$constructor=$reflector->getConstructor();”来获取类的构造方法,当该类存在构造函数时,返回一个ReflectionMethod对象,相当于获取构造函数的反射类,当类不存在构造函数时返回NULL,最后通过“is_null($constructor)”判断是否存在构造函数,如果不存在则直接实例化该类,如果存在则通过“$dependencies=$constructor->getParameters();”来获取构造函数依赖的输入参数。下面将解决构造函数中依赖参数的问题,进而实现依赖注入。文件:Illuminate\Container\Container.php

依赖和依赖注入的概念将会在Laravel框架中的设计模式章节详细介绍,这里可以简单地理解为获取类构造函数中的参数,进而完成类的实例化。首先,通过“$parameters=$this->keyParametersByArgument($dependencies,$parameters);”获取直接提供的实参,未直接提供的通过“$instances=$this->getDependencies($dependencies,$parameters);”根据形参的类型取实参。在getDependencies()函数中需要调用resolveNonClass()函数或resolveClass()函数解决参数依赖问题,对于构造函数的参数,如果无法获取该参数的类名,则通过resolveNonClass()函数获取默认的参数值,如果可以获取类的名称,则通过resolveClass()函数进行实例化,而实例化过程是通过服务容器进行解析的,即通过“$parameter->getClass()->name”来获取参数的类名,然后通过“$this->make($parameter->getClass()->name);”来解析服务,make()函数接下来还会调用build()函数完成类的实例化过程,相当于一个递归调用的过程,最终由“$reflector->newInstanceArgs($instances);”实例化服务类,进而完成服务的解析。这部分内容涉及到很多新的概念,如依赖注入、服务容器、服务解析等,这里读者只需要对反射机制有一个了解就可以了,随着介绍的深入会真正理解其本质。

猜你喜欢

转载自blog.csdn.net/aa19891204/article/details/81211615