[关闭]
@a5635268 2016-02-06T21:09:51.000000Z 字数 4777 阅读 1128

YII框架之主体与组件

源码分析与使用笔记


应用主体

Yii有两种应用主体: yii\web\Application and yii\console\Application, 如名称所示,前者主要处理网页请求,后者处理控制台请求。

具体参考: http://www.yiichina.com/doc/guide/2.0/structure-applications

  1. new yii\web\Application($config); //在构造函数中Yii::$app = $this;
  2. YII::$app; //这个就是应用主体,也是服务定位器

属性

别名 yii\base\Application::aliases

可以理解为字符串别名,可通过web.ph配置或者 Yii::setAlias()来设置

  1. # 配置在web.php中
  2. 'aliases' => [
  3. '@foo' => '/path/to/foo',
  4. '@bar' => 'http://www.example.com',
  5. ]
  6. //可以在入口脚本run()前调用,它其实是baseYII里面的方法
  7. // 文件路径的别名
  8. Yii::setAlias('@foo', '/path/to/foo');
  9. // URL 的别名
  10. Yii::setAlias('@bar', 'http://www.example.com');
  11. Yii::setAlias('@foobar', '@foo/bar');
  12. Yii::setAlias('@foo', '/path/to/foo');
  13. Yii::setAlias('@foo/bar', '/path2/bar');
  14. echo Yii::getAlias('@foo/test/file.php'); // 输出:/path/to/foo/test/file.php
  15. echo Yii::getAlias('@foo/bar/file.php'); // 输出:/path2/bar/file.php

引导启动组件 yii\base\Application::bootstrap

这个属性很实用,它允许你用数组指定启动阶段yii\base\Application::bootstrap()需要运行的组件,可以配置以下任意一项来使组件来运行时初始化;

  1. [
  2. 'bootstrap' => [
  3. // 应用组件ID或模块ID,需要在modules和components配置过(键名)
  4. 'demo',
  5. //如果模块ID和应用组件ID同名,优先使用应用组件ID,如果你想用模块ID,可以使用如下无名称函数返回模块ID
  6. function () {
  7. return Yii::$app->getModule('user');
  8. },
  9. // 类名
  10. 'app\components\Profiler',
  11. // 配置数组
  12. [
  13. 'class' => 'app\components\Profiler',
  14. 'level' => 3,
  15. ],
  16. // 无名称函数
  17. function () {
  18. return new app\components\Profiler();
  19. }
  20. ],
  21. ]

开发环境下会在启动阶段运行 debug 和 gii 模块

  1. if (YII_ENV_DEV) {
  2. //这里就是指定了模块ID
  3. $config['bootstrap'][] = 'debug';
  4. $config['modules']['debug'] = 'yii\debug\Module';
  5. $config['bootstrap'][] = 'gii';
  6. $config['modules']['gii'] = 'yii\gii\Module';
  7. }

处理所有请求的控制器方法 yii\web\Application::catchAll

  1. # 可以在配置处指定,如果要维护升级的时候提供提示
  2. [
  3. 'catchAll' => [
  4. 'offline/notice', //控制器路由,也就是r
  5. 'param1' => 'value1', //传递的参数
  6. 'param2' => 'value2',
  7. ],
  8. ]

组件配置 yii\base\Application::components

  1. [
  2. 'components' => [
  3. //键名就组件ID
  4. 'cache' => [
  5. 'class' => 'yii\caching\FileCache',
  6. ],
  7. 'user' => [
  8. 'identityClass' => 'app\models\User',
  9. 'enableAutoLogin' => true,
  10. ],
  11. ],
  12. ]

在应用中可以任意注册组件,并可以通过表达式 \Yii::$app->ComponentID 全局访问。这其实是一个服务定位器的实现方式,具体的可以去参考相关内容

控制器别名 yii\base\Application::controllerMap

  1. [
  2. 'controllerMap' => [
  3. [
  4. //数组的键代表控制器ID,数组的值代表对应的类名。
  5. //访问account就等于访问UserController
  6. 'account' => 'app\controllers\UserController',
  7. 'article' => [
  8. 'class' => 'app\controllers\PostController',
  9. 'enableCsrfValidation' => false,
  10. ],
  11. ],
  12. ],
  13. ]

模块集 yii\base\Application::modules

全局参数 yii\base\Application::params

  1. [
  2. 'params' => [
  3. //缩略图尺寸
  4. 'thumbnail.size' => [128, 128],
  5. ],
  6. ]
  7. $size = \Yii::$app->params['thumbnail.size'];

默认路由 yii\base\Application::defaultRoute

默认布局文件 yii\base\Application::layout

应用主体事件

除了用on来捕获以外,还可以在配置文件中设置捕获事件后对应的操作

  1. [
  2. //on eventName(事件名)
  3. 'on beforeRequest' => function ($event) {
  4. // ...
  5. },
  6. ]

主要有以下事件可以使用

  1. yii\base\Application::EVENT_BEFORE_REQUEST; //beforeRequest: 应用处理请求之前
  2. yii\base\Application::EVENT_AFTER_REQUEST; //afterRequest: 应用处理请求之后但在返回响应之前触发
  3. yii\base\Application::EVENT_BEFORE_ACTION; //beforeAction: 每个 控制器动作 运行之前会被触发
  4. [
  5. //事件的参数为一个 yii\base\ActionEvent 实例, 事件处理中可以设置yii\base\ActionEvent::isValid 为 false 停止运行后续动作
  6. //注意 模块 和 控制器 都会触发 beforeAction 事件。 应用主体对象首先触发该事件,然后模块触发(如果存在模块),最后控制器触发。 任何一个事件处理中设置 yii\base\ActionEvent::isValid 设置为 false 会停止触发后面的事件。
  7. 'on beforeAction' => function ($event) {
  8. if ($someCondition) {
  9. $event->isValid = false;
  10. } else {
  11. }
  12. }
  13. ];
  14. yii\base\Application::EVENT_AFTER_ACTION; //afterAction: 每个 控制器动作 运行之后会被触发
  15. [
  16. //注意 模块 和 控制器 都会触发 afterAction 事件。 这些对象的触发顺序和 beforeAction 相反,也就是说,控制器最先触发,然后是模块(如果有模块),最后为应用主体
  17. 'on afterAction' => function ($event) {
  18. if ($someCondition) {
  19. // 修改 $event->result,result就是程序输出的内容,并且$event里面包含了所有控制器与方法的信息
  20. } else {
  21. }
  22. },
  23. ];

应用组件

http://www.yiichina.com/doc/guide/2.0/structure-application-components

  1. [
  2. 'components' => [
  3. // 使用类名注册 "cache" 组件
  4. 'cache' => 'yii\caching\ApcCache',
  5. // 使用配置数组注册 "db" 组件
  6. 'db' => [
  7. 'class' => 'yii\db\Connection',
  8. 'dsn' => 'mysql:host=localhost;dbname=demo',
  9. 'username' => 'root',
  10. 'password' => '',
  11. ],
  12. // 使用函数注册"search" 组件
  13. 'search' => function () {
  14. return new app\components\SolrService;
  15. },
  16. ],
  17. ]
  18. //引导启动组件
  19. [
  20. 'bootstrap' => [
  21. // 将 log 组件 ID 加入引导让它始终载入
  22. 'log',
  23. ],
  24. 'components' => [
  25. 'log' => [
  26. // "log" 组件的配置
  27. ],
  28. ],
  29. ]
  30. \Yii::$app->componentID

一般只有那些使用很频繁的组件才在配置处定义;其他的最好通过服务定位器动态注册;

组件

组件是 Yii 应用的主要基石。是 yii\base\Component 类或其子类的实例。三个用以区分它和其它类的主要功能有:

当继承 yii\base\Component 或 yii\base\Object 时,推荐你使用如下的编码风格:

  1. namespace yii\components\MyClass;
  2. use yii\base\Object;
  3. class MyClass extends Object
  4. {
  5. public $prop1;
  6. public $prop2;
  7. //传入 $config 作为构造器方法最后一个参数,然后把它传递给父类的构造方法。
  8. public function __construct($param1, $param2, $config = [])
  9. {
  10. // ... 配置生效前的初始化过程
  11. parent::__construct($config); //永远在你重写的构造方法结尾处调用一下父类的构造方法。
  12. }
  13. public function init()
  14. {
  15. parent::init(); //init 方法的开头处调用了父类的 init 方法。
  16. // ... 配置生效后的初始化过程
  17. }
  18. }
  19. # 组件调用方法
  20. $component = new MyClass(1, 2, ['prop1' => 3, 'prop2' => 4]);
  21. // 方法二:
  22. $component = \Yii::createObject([
  23. 'class' => MyClass::className(),
  24. 'prop1' => 3,
  25. 'prop2' => 4,
  26. ], [1, 2]);

属性

http://www.yiichina.com/doc/guide/2.0/concept-properties

也就是通过魔术方法实现getter与setter

  1. namespace app\components;
  2. use yii\base\Object;
  3. class Foo extend Object
  4. {
  5. private $_label;
  6. public function getLabel()
  7. {
  8. return $this->_label;
  9. }
  10. public function setLabel($value)
  11. {
  12. $this->_label = trim($value);
  13. }
  14. }
  15. // 等效于 $label = $object->getLabel();
  16. $label = $object->label;
  17. // 等效于 $object->setLabel('abc');
  18. $object->label = 'abc';
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注