PHP的反射类与实例化对象作用相反,实例化是调用封装类中的方法、成员,而反射类则是拆封类中的所有方法、成员变量,并包括私有方法等。就如“解刨”一样,我们可以调用任何关键字修饰的方法、成员。当然在正常业务中是建议不使用,比较反射类已经摒弃了封装的概念。
本章讲解反射类的使用及Laravel对反射的使用。
反射反射类是PHP内部类,无需加载即可使用,你可以通过实例化 ReflectionClass 类去使用它。
方法这里列举下PHP反射类常用的方法
方法名注释ReflectionClass::getConstant获取定义过的一个常量ReflectionClass::getConstants获取一组常量ReflectionClass::getConstructor获取类的html' target='_blank'>构造函数ReflectionClass::getDefaultProperties获取默认属性ReflectionClass::getDocComment获取文档注释ReflectionClass::getEndLine获取最后一行的行数ReflectionClass::getFileName获取定义类的文件名ReflectionClass::getInterfaceNames获取接口(interface)名称ReflectionClass::getMethods获取方法的数组ReflectionClass::getModifiers获取类的修饰符ReflectionClass::getName获取类名ReflectionClass::getNamespaceName获取命名空间的名称ReflectionClass::getParentClass获取父类等等等等.... 所有关于类的方法、属性及其继承的父类、实现的接口都可以查询到。
详细文档请参考网址
?php namespace A/B; class Foo { } $function = new /ReflectionClass( stdClass var_dump($function- 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) FooLaravel
Laravel在实现服务容器加载时使用了反射类。现在我们开启“解刨”模式
入口文件index.php$app = require_once __DIR__. /../bootstrap/app.php |--------------------------------------------------------------------------| Run The Application|--------------------------------------------------------------------------| Once we have the application, we can handle the incoming request| through the kernel, and send the associated response back to| the client s browser allowing them to enjoy the creative| and wonderful application we have prepared for them.$kernel = $app- make(Illuminate/Contracts/Http/Kernel::class);$response = $kernel- handle( $request = Illuminate/Http/Request::capture()$response- send();$kernel- terminate($request, $response);
是引用语句发生的下一行调用了make方法。各位很清楚,make方法用于解析类,所有make方法的实现一定是在引用的文件内。
bootstrap/app.php$app = new Illuminate/Foundation/Application( realpath(__DIR__. /../ ));
laravel开始加载它的核心类,所有的实现从 Illuminate/Foundation/Application 开始。
Illuminate/Foundation/Applicationpublic function make($abstract, array $parameters = []) $abstract = $this- getAlias($abstract); if (isset($this- deferredServices[$abstract]) ! isset($this- instances[$abstract])) { $this- loadDeferredProvider($abstract); return parent::make($abstract, $parameters);}
在核心类中你可能准确的查找到make方法的存在,它加载了服务提供者随后调用了父类的方法make,要知道作为独立的模块 “服务容器”是绝对不能写在核心类的。懂点设计模式的都很清楚。
Illuminate/Container/Container以 $api = $this- app- make( HelpSpot/API ,[ id = 为例来讲解
// 真正的make方法,它直接调用了resolve继续去实现make的功能// $abstract = HelpSpot/API public function make($abstract, array $parameters = []) // $abstract = HelpSpot/API return $this- resolve($abstract, $parameters);protected function resolve($abstract, $parameters = []) // 判断是否可以合理反射 // $abstract = HelpSpot/API if ($this- isBuildable($concrete, $abstract)) { // 实例化具体实例 (实际并不是实例化,而是通过反射“解刨”了) $object = $this- build($concrete); } else { $object = $this- make($concrete);public function build($concrete) // $concrete = HelpSpot/API if ($concrete instanceof Closure) { return $concrete($this, $this- getLastParameterOverride()); // 实例化反射类 $reflector = new ReflectionClass($concrete); // 检查类是否可实例化 if (! $reflector- isInstantiable()) { return $this- notInstantiable($concrete); $this- buildStack[] = $concrete; // 获取类的构造函数 $constructor = $reflector- getConstructor(); if (is_null($constructor)) { array_pop($this- buildStack); return new $concrete; $dependencies = $constructor- getParameters(); $instances = $this- resolveDependencies( $dependencies array_pop($this- buildStack); // 从给出的参数创建一个新的类实例。 return $reflector- newInstanceArgs($instances);}
可见一个服务容器就加载成功了。
以上就是php反射类的使用及Laravel对反射的使用介绍的详细内容,PHP教程
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。
新闻热点
疑难解答