Home  >  Article  >  Backend Development  >  A brief analysis of the componentization mechanism of Yii framework

A brief analysis of the componentization mechanism of Yii framework

*文
*文Original
2018-01-05 17:21:201711browse

This article mainly introduces the basic knowledge of the componentization mechanism of PHP's Yii framework, and briefly analyzes the CWebApplication component of the application. Friends in need can refer to it.

Components are the main cornerstone of Yii applications. Is an instance of the yii\base\Component class or its subclasses. The three main functions used to distinguish it from other classes are:

  • Property

  • Event

  • Behavior

Either used alone or in conjunction with each other, the application of these functions makes Yii classes more flexible and easier to use. Take the widget yii\jui\DatePicker as an example. This is a UI component that facilitates you to generate an interactive date picker in the view:

use yii\jui\DatePicker;

echo DatePicker::widget([
  'language' => 'zh-CN',
  'name' => 'country',
  'clientOptions' => [
    'dateFormat' => 'yy-mm-dd',
  ],
]);

This widget inherits from yii\base\Component, and its various Item properties can be easily overridden.

Precisely because of the powerful functions of components, they are slightly heavier than regular objects (Object) because they use additional memory and CPU time to process events and behaviors. If you don't need these two features, you can inherit yii\base\Object instead of yii\base\Component. In this way, the component can be as efficient as a normal PHP object, while also supporting the property function.

When inheriting yii\base\Component or yii\base\Object, it is recommended that you use the following coding style:

If you need to override the constructor (Constructor), pass in $config As the last parameter of the constructor method, pass it to the constructor of the parent class.
Always call the constructor of the parent class at the end of the constructor you override.
If you override the yii\base\Object::init() method, please make sure you call the init method of the parent class at the beginning of the init method.
Examples are as follows:

namespace yii\components\MyClass;

use yii\base\Object;

class MyClass extends Object
{
  public $prop1;
  public $prop2;

  public function __construct($param1, $param2, $config = [])
  {
    // ... 配置生效前的初始化过程

    parent::__construct($config);
  }

  public function init()
  {
    parent::init();

    // ... 配置生效后的初始化过程
  }
}

In addition, in order for the component to be correctly configured when creating an instance, please follow the following operation process:

$component = new MyClass(1, 2, ['prop1' => 3, 'prop2' => 4]);
// 方法二:
$component = \Yii::createObject([
  'class' => MyClass::className(),
  'prop1' => 3,
  'prop2' => 4,
], [1, 2]);

Additional: Even if you call Yii::createObject( ) method looks more complicated, but this is mainly because it is more flexible and powerful, and it is implemented based on a dependency injection container.
yii\base\Object class execution life cycle is as follows:

Pre-initialization process within the constructor. You can set default values ​​for each property here.
Configure the object through $config. The configuration process may overwrite the default values ​​previously set in the constructor.
Perform the finishing work after initialization in the yii\base\Object::init() method. You can override this method to perform some work such as quality inspection and attribute initialization.
Object method call.
The first three steps all occur within the object's construction method. This means that once you obtain an object instance, it is initialized and ready for use.

Application CWebApplication component
Before explaining how to use each component in Yii, let’s first understand the most important component, CWebApplication. CWebApplication is the application object, and its root class is also CComponent, so it is also a component and has the common characteristics of Yii components.
Specifically, the main function of the CWebApplication component is to load necessary auxiliary components according to the configuration file, and create and run the controller with the help of these components (such as urlManager). Therefore, it is also called a front-end controller.
We can specify the configuration parameters of the CWebApplication component itself in the configuration file. These parameters are set to its public member variables, or the setter method is automatically called to set properties. This feature can be found in the constructor of CWebApplication: $this- >configure($config);
As specified in the configuration file protected/config/main.php globally:

'charset' => 'utf-8',

This is actually setting the charset public property of the current application (declared in CApplication) And if 'language' => 'zh_cn' is specified in the configuration file, we find that CWebApplication and all its superior classes do not declare the $language attribute. In this case, the setter mode method, setlanuage, will be used (this method is defined in the CApplication class) .
OK, after understanding this feature, we can understand the properties that can be configured in the configuration file:

  • Public member variables of CWebApplication and all its superior classes

  • The properties specified by the setter methods of CWebApplication and all its superior classes. Of course, we can also construct our own application class by inheriting CWebApplication.

The inheritance hierarchy of CWebApplication is: CApplication -> CModule -> CComponent. We will explain the common configuration items in the default configuration file and their effective locations:

  • basePath : CApplication::setBasePath()

  • name: CApplication::$name

  • preload: CModule ::$preload

  • import: CModule::setImport()

  • defaultController: CWebApplication::$defaultController

  • components: CModule::setComponents()

Similarly, list several configuration items that are not listed in the default configuration file: timezone: CApplication:: setTimeZone() #Configure time zone

再例如,如果我们继承CWebApplication, 扩展自己的应用程序类myApp, 并定义方法setError_reporting(不区分大小写), 那么就可以直接在配置文件中指定error_reporting选项。
辅助组件可以将CWebApplication组件视为一部机器,那么辅助组件就可以视为组成这部机器的各个零件,没有零件的正确组合,机器就无法正常工作,这在Yii中也是同样的概念。而一些组件对整部机器的运转是必须的,这就是核心组件。在应用程序对象构造后,Yii会将辅助组件基本信息进行登记(组件名称与类名,属性配置的对照表),以供后续使用,对web应用程序而言,存在以下核心组件(通过CWebApplication::registerCoreComponents,CApplication::registerCoreComponents注册):

CWebApplication::registerCoreComponents中注册的核心组件

2016317152903914.png (629×145)

CApplication::registerCoreComponents中注册的核心组件

2016317152921101.png (645×160)

配置文本中注册的核心组件:log CLogRouter 日志路由管理器
以上标记为红色的条目,是最重要的辅助组件,其它的核心组件我们未必会使用到。
如何定义辅助组件的属性?通过在配置文件protected/config/main.php中设置components项的值,实现组件属性定义。这里的定义主要是三个要素:指定组件的名称(核心组件已经预先设置)、指定组件使用的类(核心组件无须定义),组件的属性(可选、视情况而定)
如以下配置:

'components' => array(
'db' => array(
'class' => 'myCDbConnection',
'connnectionString' => 'mysql:host=localhost;dbname=test;charset=utf8',
'user' => 'root',
),
);

就设置了db组件使用的类为myCDbConnection, 并且在后面指定了连接串及账号等信息。提示: myCDbConnection类可能就是通过继承CDbConnection类定义。核心组件无须指定class参数(因为已经预先定义好)
问题:如何得知某个组件可配置的属性?这个问题至关重要,如果我们掌握了规律,就可以举一反三,所有组件的配置均可以灵活设定。授之以鱼不如授之以渔。在本节会说明通用的方法。要得知组件的所有可定义属性,按以下步骤进行:
1. 组件所使用的类是什么?(无论是核心组件还是自定义组件)
2. 组件类的公共成员变量都有哪些?(注意从父类继承而来的公共成员变量)
3. 组件类都有哪些settter方法?(注意从父类继承而来的方法)
明白了以上三个要点,我们就可以按规律定义组件的属性,比如对最重要的db组件,我们发现这是一个核心组件,使用的类为CDbConnection, 我们查阅这个类的定义文件,发现这个类的公共成员变量有:

$connectionString;

  • $username='';

  • $password='';

  • $autoConnect=true;

  • $charset;

  • $emulatePrepare;

  • $tablePrefix;

  • $initSQLs;

  • ... ...

setter方法定义的属性:

  • setActive($value)

  • setAttributes($values)

  • setAutoCommit($value)

  • setColumnCase($value)

  • setNullConversion($value)

  • setPersistent($value)

提示:setter方法定义的属性名称不区分大小写以上所列的属性,均可以在配置文件中指定,具体每个属性的作用,请参阅Yii类文件的详细注释(Yii代码的注释也是相当棒,通俗易懂,而又很详细)

再来一个例子,定义urlManager组件的属性这个组件使用的类为CUrlManager, 我们查阅它的属性:

  • $rules=array();

  • $urlSuffix='';

  • $showScriptName=true;

  • $appendParams=true;

  • $routeVar='r';

  • $caseSensitive=true;

通过setter方法定义的属性:

  • setUrlFormat($value)

  • setBaseUrl($value)

即urlManager组件的上述属性可以在配置文件中定义(每项配置的作用请参阅其注释)。其它组件的配置均可按上述方法处理。

如何使用组件应用程序运行后,会将所有已经定义过的组件注册(并未实例化)到CWebApplication对象上,同时CWebApplication应用程序对象会被注册到Yii::$_app,在程序的任何位置均可通过Yii::app()得到当前应用程序对象引用,再通过$app对象得到组件实例引用,如:Yii::app()->getComponent('urlManager');  #会查找组件配置并实例化之Yii::app()->urlManager;  #通过CModule::__get()魔术方法实现
如何自定义组件?这是很常见的需求,比如我们可能希望db组件(数据库连接)使用我们自定义的类,也或者我们希望使用多个数据库连接,这种情况下就需要自定义组件,使用多数据库的例子:

components=>array(
'db' => array(
... ...
),
'mydb'=>array(
'class' => 'myDbConnection',
'connectionString' => 'mysql:host=localhost;dbname=test;charset=utf8',
'tablePrefix' => 'cdb_',
'username' => 'root',
),
),
修改默认的db组件所使用的类:
components=>array(
'db' => array(
'class' => 'myDbConnection',
... ...
),
),

相关推荐:

简述Yii2队列shmilyzxt/yii2-queue

详解YII2多表关联的使用

详解yii2 csrf的局部开关

The above is the detailed content of A brief analysis of the componentization mechanism of Yii framework. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn