@a5635268
2016-02-06T13:09:51.000000Z
字数 4777
阅读 1305
源码分析与使用笔记
Yii有两种应用主体: yii\web\Application and yii\console\Application, 如名称所示,前者主要处理网页请求,后者处理控制台请求。
具体参考: http://www.yiichina.com/doc/guide/2.0/structure-applications
new yii\web\Application($config); //在构造函数中Yii::$app = $this;YII::$app; //这个就是应用主体,也是服务定位器
yii\base\Application::aliases可以理解为字符串别名,可通过web.ph配置或者 Yii::setAlias()来设置
# 配置在web.php中'aliases' => ['@foo' => '/path/to/foo','@bar' => 'http://www.example.com',]//可以在入口脚本run()前调用,它其实是baseYII里面的方法// 文件路径的别名Yii::setAlias('@foo', '/path/to/foo');// URL 的别名Yii::setAlias('@bar', 'http://www.example.com');Yii::setAlias('@foobar', '@foo/bar');Yii::setAlias('@foo', '/path/to/foo');Yii::setAlias('@foo/bar', '/path2/bar');echo Yii::getAlias('@foo/test/file.php'); // 输出:/path/to/foo/test/file.phpecho Yii::getAlias('@foo/bar/file.php'); // 输出:/path2/bar/file.php
yii\base\Application::bootstrap这个属性很实用,它允许你用数组指定启动阶段yii\base\Application::bootstrap()需要运行的组件,可以配置以下任意一项来使组件来运行时初始化;
['bootstrap' => [// 应用组件ID或模块ID,需要在modules和components配置过(键名)'demo',//如果模块ID和应用组件ID同名,优先使用应用组件ID,如果你想用模块ID,可以使用如下无名称函数返回模块IDfunction () {return Yii::$app->getModule('user');},// 类名'app\components\Profiler',// 配置数组['class' => 'app\components\Profiler','level' => 3,],// 无名称函数function () {return new app\components\Profiler();}],]
开发环境下会在启动阶段运行 debug 和 gii 模块
if (YII_ENV_DEV) {//这里就是指定了模块ID$config['bootstrap'][] = 'debug';$config['modules']['debug'] = 'yii\debug\Module';$config['bootstrap'][] = 'gii';$config['modules']['gii'] = 'yii\gii\Module';}
yii\web\Application::catchAll
# 可以在配置处指定,如果要维护升级的时候提供提示['catchAll' => ['offline/notice', //控制器路由,也就是r'param1' => 'value1', //传递的参数'param2' => 'value2',],]
yii\base\Application::components
['components' => [//键名就组件ID'cache' => ['class' => 'yii\caching\FileCache',],'user' => ['identityClass' => 'app\models\User','enableAutoLogin' => true,],],]
在应用中可以任意注册组件,并可以通过表达式 \Yii::$app->ComponentID 全局访问。这其实是一个服务定位器的实现方式,具体的可以去参考相关内容
yii\base\Application::controllerMap
['controllerMap' => [[//数组的键代表控制器ID,数组的值代表对应的类名。//访问account就等于访问UserController'account' => 'app\controllers\UserController','article' => ['class' => 'app\controllers\PostController','enableCsrfValidation' => false,],],],]
yii\base\Application::modulesyii\base\Application::params
['params' => [//缩略图尺寸'thumbnail.size' => [128, 128],],]$size = \Yii::$app->params['thumbnail.size'];
yii\base\Application::defaultRouteyii\base\Application::layout除了用on来捕获以外,还可以在配置文件中设置捕获事件后对应的操作
[//on eventName(事件名)'on beforeRequest' => function ($event) {// ...},]
主要有以下事件可以使用
yii\base\Application::EVENT_BEFORE_REQUEST; //beforeRequest: 应用处理请求之前yii\base\Application::EVENT_AFTER_REQUEST; //afterRequest: 应用处理请求之后但在返回响应之前触发yii\base\Application::EVENT_BEFORE_ACTION; //beforeAction: 每个 控制器动作 运行之前会被触发[//事件的参数为一个 yii\base\ActionEvent 实例, 事件处理中可以设置yii\base\ActionEvent::isValid 为 false 停止运行后续动作//注意 模块 和 控制器 都会触发 beforeAction 事件。 应用主体对象首先触发该事件,然后模块触发(如果存在模块),最后控制器触发。 任何一个事件处理中设置 yii\base\ActionEvent::isValid 设置为 false 会停止触发后面的事件。'on beforeAction' => function ($event) {if ($someCondition) {$event->isValid = false;} else {}}];yii\base\Application::EVENT_AFTER_ACTION; //afterAction: 每个 控制器动作 运行之后会被触发[//注意 模块 和 控制器 都会触发 afterAction 事件。 这些对象的触发顺序和 beforeAction 相反,也就是说,控制器最先触发,然后是模块(如果有模块),最后为应用主体'on afterAction' => function ($event) {if ($someCondition) {// 修改 $event->result,result就是程序输出的内容,并且$event里面包含了所有控制器与方法的信息} else {}},];
http://www.yiichina.com/doc/guide/2.0/structure-application-components
['components' => [// 使用类名注册 "cache" 组件'cache' => 'yii\caching\ApcCache',// 使用配置数组注册 "db" 组件'db' => ['class' => 'yii\db\Connection','dsn' => 'mysql:host=localhost;dbname=demo','username' => 'root','password' => '',],// 使用函数注册"search" 组件'search' => function () {return new app\components\SolrService;},],]//引导启动组件['bootstrap' => [// 将 log 组件 ID 加入引导让它始终载入'log',],'components' => ['log' => [// "log" 组件的配置],],]\Yii::$app->componentID;
一般只有那些使用很频繁的组件才在配置处定义;其他的最好通过服务定位器动态注册;
组件是 Yii 应用的主要基石。是 yii\base\Component 类或其子类的实例。三个用以区分它和其它类的主要功能有:
当继承 yii\base\Component 或 yii\base\Object 时,推荐你使用如下的编码风格:
namespace yii\components\MyClass;use yii\base\Object;class MyClass extends Object{public $prop1;public $prop2;//传入 $config 作为构造器方法最后一个参数,然后把它传递给父类的构造方法。public function __construct($param1, $param2, $config = []){// ... 配置生效前的初始化过程parent::__construct($config); //永远在你重写的构造方法结尾处调用一下父类的构造方法。}public function init(){parent::init(); //init 方法的开头处调用了父类的 init 方法。// ... 配置生效后的初始化过程}}# 组件调用方法$component = new MyClass(1, 2, ['prop1' => 3, 'prop2' => 4]);// 方法二:$component = \Yii::createObject(['class' => MyClass::className(),'prop1' => 3,'prop2' => 4,], [1, 2]);
http://www.yiichina.com/doc/guide/2.0/concept-properties
也就是通过魔术方法实现getter与setter
namespace app\components;use yii\base\Object;class Foo extend Object{private $_label;public function getLabel(){return $this->_label;}public function setLabel($value){$this->_label = trim($value);}}// 等效于 $label = $object->getLabel();$label = $object->label;// 等效于 $object->setLabel('abc');$object->label = 'abc';