@a5635268
2016-02-06T21:09:51.000000Z
字数 4777
阅读 1128
源码分析与使用笔记
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.php
echo 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,可以使用如下无名称函数返回模块ID
function () {
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::modules
yii\base\Application::params
[
'params' => [
//缩略图尺寸
'thumbnail.size' => [128, 128],
],
]
$size = \Yii::$app->params['thumbnail.size'];
yii\base\Application::defaultRoute
yii\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';