千家信息网

Object和Component的区别是什么

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章给大家介绍Object和Component的区别是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。由于Componet引入了事件、行为,因此,它并非简单继承了Objec
千家信息网最后更新 2026年11月02日Object和Component的区别是什么

这篇文章给大家介绍Object和Component的区别是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

  由于Componet引入了事件、行为,因此,它并非简单继承了Object的属性实现方式,而是基于同样的机制, 重载了 __get() __set() 等函数。但从实现机制上来讲,是一样的。这个不影响理解。

  前面说过,官方将Yii定位于一个基于组件的框架。可见组件这一概念是Yii的基础。 如果你有兴趣阅读Yii的源代码或是API文档,你将会发现, Yii几乎所有的核心类都派生于(继承自) yii\base\Component 。

  在Yii1.1时,就已经有了component了,那时是 CComponent。Yii2将Yii1.1中的CComponent拆分成两个类: yii\base\Object 和 yii\base\Component 。

  其中,Object比较轻量级些,通过getter和setter定义了类的属性(property)。 Component派生自Object,并支持事件(event)和行为(behavior)。因此,Component类具有三个重要的特性:属性(property)、事件(event)、行为(behavior)。

  相信你或多或少了解过,这三个特性是丰富和拓展类功能、改变类行为的重要切入点。 因此,Component在Yii中的地位极高。

  在提供更多功能、更多便利的同时,Component由于增加了event和behavior这两个特性, 在方便开发的同时,也牺牲了一定的效率。 如果开发中不需要使用event和behavior这两个特性,比如表示一些数据的类。 那么,可以不从Component继承,而从Object继承。 典型的应用场景就是如果表示用户输入的一组数据,那么,使用Object。 而如果需要对对象的行为和能响应处理的事件进行处理,毫无疑问应当采用Component。 从效率来讲,Object更接近原生的PHP类,因此,在可能的情况下,应当优先使用Object。

  Object的配置方法

  Yii提供了一个统一的配置对象的方式。这一方式贯穿整个Yii。Application对象的配置就是这种配置方式的体现:

  $config = yii\helpers\ArrayHelper::merge(

  require(__DIR__ . '/../../common/config/main.php'),

  require(__DIR__ . '/../../common/config/main-local.php'),

  require(__DIR__ . '/../config/main.php'),

  require(__DIR__ . '/../config/main-local.php')

  );

  $application = new yii\web\Application($config);

  $config 看着复杂,但本质上就是一个各种配置项的数组。Yii中就是统一使用数组的方式对对象进行配置,而实现这一切的关键就在 yii\base\Object 定义的构造函数中:

  public function __construct($config = [])

  {

  if (!empty($config)) {

  Yii::configure($this, $config);

  }

  $this->init();

  }

  所有 yii\base\Object 的构建流程是:

  构建函数以 $config 数组为参数被自动调用。

  构建函数调用 Yii::configure() 对对象进行配置。

  在最后,构造函数调用对象的 init() 方法进行初始化。

  数组配置对象的秘密在 Yii::configure() 中,但说破了其实也没有什么神奇的:

  public static function configure($object, $properties)

  {

  foreach ($properties as $name => $value) {

  $object->$name = $value;

  }

  return $object;

  }

  配置的过程就是遍历 $config 配置数组,将数组的键作为属性名,以对应的数组元素的值对对象的属性赋值。因此,实现Yii这一统一的配置方式的要点有:

  继承自 yii\base\Object 。

  为对象属性提供setter方法,以正确处理配置过程。

  如果需要重载构造函数,请将 $config 作为该构造函数的最后一个参数,并将该参数传递给父构造函数。

  重载的构造函数的最后,一定记得调用父构造函数。

  如果重载了 yii\base\Object::init() 函数,注意一定要在重载函数的开头调用父类的 init() 。

  只要实现了以上要点,就可以使得你编写的类可以按照Yii约定俗成的方式进行配置。这在编写代码的过程中,带来许多便利。

  像你这么聪明的,肯定会提出来,如果配置数组的某个配置项,也是一个数组,这怎么办? 如果某个对象的属性,也是一个对象,而非一个简单的数值或字符串时,又怎么办?

  这两个问题,其实是同质的。如果一个对象的属性,是另一个对象,就像Application里会引入诸多的Component一样, 这是很常见的。如后面会看到的 $app->request 中的 request 属性就是一个对象。 那么,在配置 $app 时,必然要配置到这个 reqeust 对象。 既然 request 也是一个对象,那么他的配置要是按照Yii的规矩来,也就是用一个数组来配置它。 因此,上面提到的这两个问题,其实是同质的。

  那么,怎么实现呢?秘密在于setter函数。由于 $app 在进行配置时,最终会调用 Yii::configure() 函数。 该函数又不区分配置项是简单的数值还是数组,就直接使用 $object->$name = $value 完成属性的赋值。 那么,对于对象属性,其配置值 $value 是一个数组,为了使其正确配置。 你需要在其setter函数上做出正确的处理方式。 Yii应用 yii\web\Application 就是依靠定义专门的setter函数,实现自动处理配置项的。 比如,我们在Yii的配置文件中,可以看到一个配置项 components ,一般情况下,他的内容是这样的:

  'components' => [

  'request' => [

  // !!! insert a secret key in the following (if it is empty) -

  // this is required by cookie validation

  'cookieValidationKey' => 'v7mBbyetv4ls7t8UIqQ2IBO60jY_wf_U',

  ],

  'user' => [

  'identityClass' => 'common\models\User',

  'enableAutoLogin' => true,

  ],

  'log' => [

  'traceLevel' => YII_DEBUG ? 3 : 0,

  'targets' => [

  [

  'class' => 'yii\log\FileTarget',

  'levels' => ['error', 'warning'],

  ],

  ],

  ],

  'errorHandler' => [

  'errorAction' => 'site/error',

  ],

  ],

  这是一个典型嵌套配置数组。那么Yii是如何把他们配置好的呢? 聪明的你肯定想到了,Yii一定是定义了一个名为 setComponents 的setter函数。 当然,Yii并未将该函数放在 yii\web\Application 里,而是放在父类 yii\di\ServiceLocator 里面。 至于 ServiceLocator 是何方神圣,在后面 服务定位器(Service Locator) 部分会讲到, 这里你只需要知道它是Application的父类,提供components属性的setter方法就可以了:

  public function setComponents($components)

  {

  foreach ($components as $id => $component) {

  $this->set($id, $component);

  }

  }

  这里有个成员函数, $this->set() ,他是服务定位器用来注册服务的方法。 我们暂时不讲这个东西,留待 服务定位器(Service Locator) 部分再讲。 现在只要知道这个函数把配置文件中的 components 配置项搞定就可以了。

  从 yii\base\Object::__construct() 来看,对于所有Object,包括Component的属性,都经历这么4个阶段:

  预初始化阶段。这是最开始的阶段,就是在构造函数 __construct() 的开头可以设置property的默认值。

  对象配置阶段。也就是前面提到构造函数调用 Yii::configure($this, $config) 阶段。 这一阶段可以覆盖前一阶段设置的property的默认值,并补充没有默认值的参数,也就是必备参数。 $config 通常由外部代码传入或者通过配置文件传入。

  后初始化阶段。也就是构造函数调用 init() 成员函数。 通过在 init() 写入代码,可以对配置阶段设置的值进行检查,并规范类的property。

  类方法调用阶段。前面三个阶段是不可分的,由类的构造函数一口气调用的。 也就是说一个类一但实例化,那么就至少经历了前三个阶段。 此时,该对象的状态是确定且可靠的,不存在不确定的property。 所有的属性要么是默认值,要么是传入的配置值,如果传入的配置有误或者冲突,那么也经过了检查和规范。 也就是说,你就放心用吧。

关于Object和Component的区别是什么就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

配置 函数 对象 属性 数组 阶段 就是 方式 也就是 方法 两个 参数 行为 处理 三个 事件 更多 特性 定位 服务 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 保险科技 互联网保险 重生之互联网科技帝国 互联网科技垄断 工业互联网科技新基建 北京互联网科技有限公司 金融科技 互联网金融 智网互联网科技 互联网 的科技创新 佰商互联网科技有限公司 山东吉时兔互联网科技有限公司 广州恒生互联网科技有限 福建科技产业互联网发展 智腾互联网科技有限公司 互联网科技扶贫时间 工业互联网展湾科技股份有限公司 锡山区互联网智能科技产品供应 杭州披云加互联网科技有限公司 互联网科技接地气 互联网科技收购价值 第三届互联网大会安防黑科技 广东猪兼强互联网科技有限公司 互联网科技英文 互联网科技小额贷款 汉立互联网科技有限公司联系电话 浙江互联网科技研学营 健康食品互联网创新科技园项目 互联网科技平台产品运营 长沙易易互联网科技有限公司 互联网领先科技成果宣传视频 宁波允成互联网科技有限公司
0