php反射机制详解,PHP反射机制
PHP反射机制
PHP反射机制从PHP5开始支持,做业务开发的话应该很少接触反射。我其实也是接触不多,最近在学习laravel的"优雅",就接触了到它其中的反射用法,已经我自己的看法想法。
反射
按照之前的套路,我们来看一下官方手册,官方是怎么说的。
PHP 5 具有完整的反射 API,添加了对类、接口、函数、方法和扩展进行反向工程的能力。 此外,反射 API 提供了方法来取出函数、类和方法中的文档注释。我的理解就是php反射机制能拿到类里面的属性方法,private 和 protected的也可以
以上是官方文档中给出的东西,说实话我看了感觉没什么感觉。
能get到的点就是我们能够通过这个窥探一个类所有信息,就像在别人的窗上桶了一个洞一样。
我应该怎么用,或者基于什么场景去用呢?这还是很伤的。
laravel中的反射
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方法。下面我们就来分析一下:
参数:$concreate string 类似于Model::class这种嘛,不难理解。$parameters array 参数 更不难理解了吧。
判断 $concreate 是否是匿名类(闭包),是匿名类就执行这个函数.
创建反射类,去映射这个类。
判断这个类能否被实例化,也就是看构造函数是否是private。否就抛出出异常。
在容器成员变量中数组维护这个类,反射实例调用构造函数,获取返回值。
判断返回值是否为空,如果为空就说明不需要参数依赖,那么就直接实例化。否则就获取构造函数的参数依赖,将传入的参数和依赖参数进行对照。
最后,在调用newInstanceArgs进行实例化,之后返回实例。
后记
其实在上面这个laravel中的例子已经很好的阐明了反射机制的使用方式,或许你现在的业务场景还未必能够使用到这种机制。但是,当碰到的时候请记得还有这种方式能够使用。
当你需要去实例化一个类,但是这个类对你来说完全就是封闭或者说是未知的,你可以创建反射来与映射这个类,通过一系列的探测来最终实例化这个类,尤其还在动态运行中的。
基于这种机制,其实可以玩出很多的花样。比如说能够自动生成文档。
实现MVC这种架构,使用反射自动调用实现
$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);
}
laravel中的反射帮助它解决DI容器的依赖注入的问题。
还有很多好玩的等着你自己去尝试,这种机制究竟能玩出多少花样,就看你自己怎么玩了。
php反射机制详解,PHP反射机制相关推荐
- java反射机制详解_Java反射机制详解
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反 ...
- java反射机制详解_JAVA反射机制详解_JSP/Java编程_互联网开发技术网_传播最新的编程技术_php361.com...
今天,下午在和朋友聊天的时候,聊起了反射这个话题. 我们就从下面这个段简单的代码开始吧. 这个代码输出什么,想必大部分的读者跟我一样,会很快地知道答案:0 1 2 3 4 5 6 7 8 9.事实也是 ...
- java 反射机制详解_java反射机制原理详解
反射机制:所谓的反射机制就是java语言在运行时拥有一项自观的能力.通过这种能力可以彻底的了解自身的情况为下一步的动作做准备.下面具体介绍一下java的反射机制.这里你将颠覆原来对java的理解. J ...
- php反射机制详解,PHP反射机制实现插件的可插拔设计
说PHP和ASP等同的朋友们可以就此打住了,PHP支持反射,而且还是非常的强大.好了,我们开始今天的话题. 功能描述: 页面拥有一个主导航菜单,里头有默认连接若干. 插件统一存放在一个目录,插件载入后 ...
- JDBC驱动加载机制详解以及spi机制
首先有两个问题: 1.java连接数据库时是否真的需要加载驱动? 2.JDBC如何区分多个驱动? 以下摘自:https://blog.csdn.net/buqutianya/article/detai ...
- PHP autoload机制详解
PHP autoload机制详解 转载自 jeakccc PHP autoload机制详解 (1) autoload机制概述 在使用PHP的OO模式开发系统时,通常大家习惯上将每个类的实现都存放在一个 ...
- Hadoop之Shuffle机制详解
Hadoop之Shuffle机制详解 目录 Shuffle机制 Partition分区 WritableComparable排序 Combiner合并 GroupingComparator分组(辅助排 ...
- php 反射原理,PHP反射机制详解
本文主要和大家分享PHP反射机制详解,内容包括1.自动生成文档2.实现 MVC 架构3.实现单元测试4.配合 DI 容器解决依赖,希望能帮助到大家. 1.自动生成文档 根据反射的分析类,接口,函数和方 ...
- 反射 数据类型_Java基础:反射机制详解
一.什么是反射: (1)Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法.本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取t对 ...
- 动态代理机制详解(JDK 和CGLIB,Javassist,ASM)
2019独角兽企业重金招聘Python工程师标准>>> 在运行时期可以按照Java虚拟机规范对class文件的组织规则生成对应的二进制字节码.当前有很多开源框架可以完成这些功能,如A ...
最新文章
- Maya硬表面建模学习教程 Master Hard Surface Modeling in Maya 2020
- 懒人神器 !一个创意十足的 Python 命令行工具
- EMNLP 2019 | 大规模利用单语数据提升神经机器翻译
- WebForm页面使用Ajax
- ftp连接中服务器位置,使用 FTP 连接到服务器
- P4254-[JSOI2008]Blue Mary开公司【李超树】
- WebSite和Web Application\网站与Web项目的区别
- Linux的实际操作:文件目录类的实用指令(ln history)
- Python+OpenCV:训练级联分类器(Cascade Classifier Training)
- mariadb用户群体mysql_mysql(mariadb)新建用户及用户授权管理
- DBeaver连接mysql驱动下载失败怎么办?
- linux so替换,linux 热替换so文件
- 如何将苹方字体写入html,在网页上使用苹方字体
- 使用Android Studio 创建第一个Android 应用
- 【题解】【AcWing】149. 荷马史诗
- html5动态加载图片和加载视频
- (SGPN)南加州大学 phd 王薇月:深度学习在点云分割中的应用 | 公开课视频内容分享总结
- GDOI2017旅游记
- 证券公司信息化3-经纪业务收入大概是个什么水平?一个普通投资者的开户过程是怎样的?
- VUE 保留 四位小数
热门文章
- Android NavigationView中设置menu中的item字体颜色
- ViewState - 页面状态保留
- MyBatis源码阅读(五) ---Mapper接口的获取过程
- (笔记) SpringCloud之Hystrix断路器 属性详解
- 【更新】ReSharper v2018.3发布
- 用python来部署远程程序
- (原)logstash-forwarder + logstash + elasticsearch + kibana
- CloudStack升级中文指南:4.1.x/4.2.x 至4.3版本
- Qt在VS2012中引用QtWidgets时报GLES2/gl2.h无法打开错误的解决办法
- 推荐15个在线多媒体(图片、音频、视频)编辑器,互联网营销