如何在yii2框架的di容器源码中了解反射的作用_Yii_青云站长教程网
欢迎来到站长教程网!
  • 秒到短信接口 免费试用
  • 微信支付宝接口 秒结算
  • 中文网站排名|申请加入
  • 搜索引擎全站查询
  • 查询移动网站权重数据
  • 海外主机 台湾公司直销
  • Yii

    当前位置:主页 > 网络编程 > Yii >

    如何在yii2框架的di容器源码中了解反射的作用

    时间:2019-10-10|栏目:Yii|点击:
  • 这篇文章主要介绍了关于如何在yii2框架的di容器源码中了解反射的作用,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下

    反射简介

    参考官方简介的话,PHP 5 具有完整的反射 API,添加了对类、接口、函数、方法和扩展进行反向工程的能力。 此外,反射 API 提供了方法来取出函数、类和方法中的文档注释。

    YII2框架中示例

    对于yii2框架,应该都知道di容器,对于di容器的源码这里也主要讲明Container类,先看看平时怎么使用di,就用yii2框架中注释的示例代码来展示;

    container调用示例namespace app\models; use yii\base\BaseObject; use yii\db\Connection; use yii\di\Container; interface UserFinderInterface { function findUser(); } class UserFinder extends BaseObject implements UserFinderInterface { public $db; public function __construct(Connection $db, $config = []) { $this->db = $db; parent::__construct($config); } public function findUser() { } } class UserLister extends BaseObject { public $finder; public function __construct(UserFinderInterface $finder, $config = []) { $this->finder = $finder; parent::__construct($config); } } $container = new Container; $container->set('yii\db\Connection', [ 'dsn' => '...', ]); $container->set('app\models\UserFinderInterface', [ 'class' => 'app\models\UserFinder', ]); $container->set('userLister', 'app\models\UserLister'); $lister = $container->get('userLister'); // 上述操作相当于下列实现 $db = new \yii\db\Connection(['dsn' => '...']); $finder = new UserFinder($db); $lister = new UserLister($finder);

    上面的示例代码只是实例化了Container类,然后调用set方法注入了其他对象,最后获取到了依赖与其他对象创建的lister对象,既然只调用了set方法与get方法,那就先从调用最多的set开始看Container代码。

    set方法public function set($class, $definition = [], array $params = []) { $this->_definitions[$class] = $this->normalizeDefinition($class, $definition); $this->_params[$class] = $params; unset($this->_singletons[$class]); return $this; }

    上面的代码比较简洁,调用了类的normalizeDefinition方法,这个一会再说,先说明在该方法中出现的三个属性的含义

    _definitions数组,保存依赖定义

    _params数组,保存构造函数的参数

    _singletons,保存单例

    再看normalizeDefinition方法,该方法主要作用是规范类定义

    protected function normalizeDefinition($class, $definition) { if (empty($definition)) { // 为空 return ['class' => $class]; } elseif (is_string($definition)) { // 为字符串 return ['class' => $definition]; } elseif (is_callable($definition, true) || is_object($definition)) { // 检验是否为可调用函数或者对象 return $definition; } elseif (is_array($definition)) { // 检测是否为数组 if (!isset($definition['class'])) { if (strpos($class, '\\') !== false) { $definition['class'] = $class; } else { throw new InvalidConfigException('A class definition requires a "class" member.'); } } return $definition; } throw new InvalidConfigException("Unsupported definition type for \"$class\": " . gettype($definition)); }

    上述代码中已做了一些判断注释,不难发现最后需要返回的definition变量需要为数组格式,或者可调用函数与对象,注意回到刚开始的调用示例代码,definition变量分别有数组格式不带class键,
    数组格式带class键,与字符串类型。到底set方法调用已完毕,从源码中分析基本上看不到反射的影子,也就是些传入参数格式兼容处理再写入类属性,接着来看下示例代码中的get方法吧。

    get 方法public function get($class, $params = [], $config = []) { if (isset($this->_singletons[$class])) { // 直接返回单例 return $this->_singletons[$class]; } elseif (!isset($this->_definitions[$class])) { // 调用bulid return $this->build($class, $params, $config); } $definition = $this->_definitions[$class]; if (is_callable($definition, true)) { // 可调用函数情况 $params = $this->resolveDependencies($this->mergeParams($class, $params)); $object = call_user_func($definition, $this, $params, $config); } elseif (is_array($definition)) { // 数组 $concrete = $definition['class']; unset($definition['class']); $config = array_merge($definition, $config); $params = $this->mergeParams($class, $params); if ($concrete === $class) { $object = $this->build($class, $params, $config); } else { $object = $this->get($concrete, $params, $config); } } elseif (is_object($definition)) { // 对象直接保存到单例属性集合中去 return $this->_singletons[$class] = $definition; } else { throw new InvalidConfigException('Unexpected object definition type: ' . gettype($definition)); } if (array_key_exists($class, $this->_singletons)) { // singleton $this->_singletons[$class] = $object; } return $object; }

    上一篇:PHP的安装以及与apache整合的介绍

    栏    目:Yii

    下一篇:phpstorm怎么格式化代码

    本文标题:如何在yii2框架的di容器源码中了解反射的作用

    本文地址:http://www.jh-floor.com/wangluobiancheng/Yii/86811.html

    广告投放 | 联系我们 | 版权申明

    重要申明:本站所有的文章、图片、评论等,均由网友发表或上传并维护或收集自网络,属个人行为,与本站立场无关。

    如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。

    联系QQ:888888 | 邮箱:888888#qq.com(#换成@)

    Copyright © 2002-2017 青云站长教程网 版权所有 琼ICP备xxxxxxxx号