Yii2 的请求、执行、响应原理(只给刚接触 Yii 的人看,大牛莫吐槽) [ 新手入门 ]
先从一个地址讲起例如下面的地址:
yii一个地址 http://yii4.local.com/index.php?XDEBUG_SESSION_START=1
返回结果:页面显示 12345678
这个结果怎么显示的呢?如果我们自己写一个 index.php
然后里面写 echo 12345678
一样达到效果。
这里说的不是这么简单,包含了请求,处理,响应三个阶段。而yii的其他部分组件全部摘除了(保留了核心的容器,服务提供器等)
首先查看 web
目录下的 index.php
会看 new
了一个 yii\web\Application($config)
。
然后执行->run();
而 yii\web\Application
的父类是 yii\base\Application
,看一下父类的构造函数
只看里面的 $this->preInit(&$config);
(现在还不熟悉看其他的会很迷糊)
在 preInit()
里都做了什么呢?只看 preInit()
方法里的 foreach($this->coreComonents() as $id=>$component)
这里的意思是yii内部使用的组件先要加载进去。(加载这个词看似很屌),就解释一下 “加载”。
1 在讲“加载”之前先交代一下yii封装好的容器(容器就是你给他一个类地址或回调)它返回给你这个类的对象(同时如果类有依赖会自动解决依赖,不用你操心)。这个容器也不先不用管。只知道它这个作用就行。
2
再将yii利用了php的魔术函数__get()
,__set()
(当获取一个属性不存在时自动执行)
然后回到上面的
foreach($this->coreComonents() as $id=>$component)
{
}
$this->coreComonents()
(在 yii\web\Application
里有这个方法,父类也有)里面定义了request和response
这两个就是yii的请求和响应。
然后开始上面的 foreach
循环就是把这个定义好的组件放到 $config
数组里。(这里的 $config
数组就是项目下main.php的配置项目,只不过yii在这里而外追加了一些必须的配置)。注意上面数组的key是:components写死的这里后面会讲。
好了,现在 $confgi
有内容了就是key组件名,value是组件的类命名空间地址。
然后执行了 Component::__construct($config);
(也就是$config
内容都准备好了,开始发动把)
在往里看。看到了 Yii::config($this,$config);
这句就是给当前对象 $this
的属性赋值。
而 $this
的属性是什么呢?就是 $config
里的 key
值。记得上面提到的注意的 components
了吧。
其实现在的 $config
样子大概是
$config = [
'components' => ['request' => ['class'=>'yii\web\Request']]
]
//下面是重点
public static function configure($object,$properties)
{
foreach($properties as $name => $value){
$object->$name = $value
//实际执行的是 $this->components = ['request' => ['class'=>'yii\web\Request']]
}
但是 yii/web/Application
里面没有定义 components
这个属性啊
会看上面讲的,如果php访问未定义的属性会访问 __get()
,如果给未定义的属性赋值会执行 __set()
.
__get()
和 __set()
在哪里了呢?看 yii\base\Application
的父类是 yii\base\Module->yii\base\module->yii\di\ServiceLocator->yii\base\Component
好了,在Component类里面会看到这两个__get()
,和 __set()
方法。
上面执行 $this->components = ['request' => ['class'=>'yii\web\Request']]
没有这个components方法,那么就通过 __set()
. 在前面价格set变成 setComponents();
最后看看有没有这个方法,发现有:在看 yii\base\Application
的父类是 yii\base\Module->yii\base\module->yii\di\ServiceLocator
在 serviceLocator
里。
这里又一个foreach()。而这里的foreach就是对每个组件的定义赋值.
循环的内容是:['request' => ['class'=>'yii\web\Request']]
把这个 key=>value 先放到一个数组里$this->_definitions
然后就不管里。
然后后面执行->run()
(上面提到了,也就是大概初始化过程完事了)
把请求和响应组件定义都放在数组里准备好了,如果有地方用到就去实例化;
run里用到了request $this->getRequest();
这时候就回去容器里要一个对象
要哪个对象呢。
public function getRequest()
{
$this->get('request'); //这个key也就是前面初始化组件的key
}
然后容器根据key找到了value['class'=>'yii\web\Request']
然后根据这个地址就能实例化了。然后
$request
对象就获取到了。然后根据$request
对象去解析请求地址里包含的模型,控制器,方法(action)
然后执行action把结果赋值给response->data
。这里的response对象和request对象获取逻辑一样。
然后respons里会echo $this->content
;在这之前会把$response->data
(是执行action的返回值)的值给$response->content
。。然后在执行echo $this->content
时就会输出action的内容了。
共 0 条回复
灰太狼
最后登录:2023-07-14
在线时长:76小时17分
- 粉丝28
- 金钱3290
- 威望150
- 积分5550