yii2深刻理解以内核解析

1、前言php

 

首先,yii2最为为数很少的PHP主流开源框架,受欢迎程度不亚于laravel和TP。我的认为,研究这些框架底层代码是很是有助于自身代码编程思想的提高和代码简化程度和质量的提高的。css

那么,话很少说,下面开始说一下本身对yii2底层框架架构的理解。前端

2、客户端请求处理nginx

 

yii2对客户请求处理,提供了url美化类urlManager,这点在最初经过composer加载,并初始化框架时,已经在config目录下的main文件里生成了, 只不过期注释过的,若是须要url美化则取消掉注释便可。其实,yii2对apache的支持是很是的好的。laravel

说到这了,那么咱们就说一下,后端最流行的两个服务器,apache和nginx的区别。web

a、nginx性能比apache要好不少,相比apache,但bug就会相对多。算法

b、nginx相比apache轻量级了很多,配置也相对简单,并且,对高并发的请求事件处理,能够是异步非阻塞的处理请求,能消耗低。数据库

c、apache相比nginx,它的重写能力要比nginx强不少,并且,功能模块比nginx多不少,其性能比nginx稳定,bug较少。apache

因此说,yii2的url美化组件urlManager对apache服务器有很好的支持。编程

框架和项目配置,咱们能够直接在common文件下的config文件下的main-local文件里配置,数据库的链接以及数据表的前缀等。web文件夹下的.htaccess文件内容以下:

 1  Header always set Access-Control-Allow-Origin "*"
 2  Header always set Access-Control-Allow-Headers: "X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding"
 3  RewriteEngine ON
 4  RewriteCond %{REQUEST_FILENAME} !-f
 5  RewriteCond $1 !^(index\.php|robots\.txt|favicon\.ico|Sitemap\.xml|pma)
 6  RewriteRule ^(.*)$ index.php/$1 [L]
 7  php_value upload_max_filesize "50M"
 8 php_value post_max_size "50M"
 9 php_value max_execution_time "40000"
10 php_value memory_limit "128M"

代码解析一下:

RewriteEngine On

指令含义:命令apache或nginx重写功能开启。

RewriteCond %{REQUEST_FILENAME} !-f

指令含义:URI匹配内容为非文件。

RewriteCond $1 !^(index\.php|robots\.txt|favicon\.ico|Sitemap\.xml|pma)

指令含义:URI匹配内容非文件,除了这几个文件。注:这里用到了正则的反引用。

RewriteRule ^(.*)$ index.php/$1 [L]

指令含义:URL匹配规则,index.php/site/login

下面来看一下web目录下的文件都有哪些:

a. assets yii2底层必备静态文件夹,这里放了一些,yii2静态模板组件的必须引入的静态文件。如:jQuery,bootstrap等。注:此文件夹不可删除;

assets文件夹下面的文件,在你第一次访问项目时,会自动生成静态文件,这里用到了yii2的另一个服务和组件assetManager,在它的里面有一个方法,publish(),其具体用法以下:

1 <?php
2 
3 list(, $dir) = Yii::$app->getAssetManager()->publish('@backend/rbac/plugins');
4 $svg = $dir . '/image/loading.svg';

此方法须要传入一个alias路由,这alias路由其实在common文件下的config文件夹下的bootstrap.php已经配置。代码以下:

1 <?php
2 Yii::setAlias('@common', dirname(__DIR__));
3 Yii::setAlias('@frontend', dirname(dirname(__DIR__)) . '/frontend');
4 Yii::setAlias('@backend', dirname(dirname(__DIR__)) . '/backend');
5 Yii::setAlias('@console', dirname(dirname(__DIR__)) . '/console');
6 Yii::setAlias('@wechat', dirname(dirname(__DIR__)) . '/wechat');
7 Yii::setAlias('@api', dirname(dirname(__DIR__)) . '/api');

当传入alias路由,此方法会解析出文件绝对路由,并在assets文件夹下生成对应的文件夹和其文件。这个方法用到了crc32()多项冗余算法,经过文件名和文件修改时间,生成带有符号的crc32值,并经过sprinf()转换为16进制字符做为文件名。

b.css文件这里面写入了项目须要引入的前端静态文件,好比:css,js,svg,图片等;

3、index.php脚本文件运行机制


项目脚本文件,最后一行简洁的代码,包含了yii2架构全部运行的机制。

<?php
(new yii\web\Application($config))->run();


这里有几个类:

1.yii\web\Application

2.yii\base\Application

3.yii\base\Module

4.yii\di\ServiceLocator

5.yii\base\component

6.yii\base\BaseObject

首先,new yii\web\Application类,这里的构造函数在yii\base\Application下:

1 public function __construct($config = [])
2 {
3 Yii::$app = $this;
4 static::setInstance($this);
5 
6 $this->state = self::STATE_BEGIN;
7 
8 $this->preInit($config);
9 
10 $this->registerErrorHandler($config);
11 
12 Component::__construct($config);
13 }


这里它作了什么?

1.单例yii\web\Application应用核心类。

2.注册yii\web\Application模块到注册树。

3.指定web应用运行状态:初始化

4.初始化配置,拉入common和backend目录下config目录下bootstrap.php文件配置。

5.注册错误处理程序。

6.加载核心组件、核心配置、以及自定义行为组件等。(注:这些都是common和backend文件下config文件下main.php里面的内容)

接下来运行run方法:

1 public function run()
2 {
3 try {
4 $this->state = self::STATE_BEFORE_REQUEST;
5 $this->trigger(self::EVENT_BEFORE_REQUEST);
6 
7 $this->state = self::STATE_HANDLING_REQUEST;
8 $response = $this->handleRequest($this->getRequest());
9 
10 $this->state = self::STATE_AFTER_REQUEST;
11 $this->trigger(self::EVENT_AFTER_REQUEST);
12 
13 $this->state = self::STATE_SENDING_RESPONSE;
14 $response->send();
15 
16 $this->state = self::STATE_END;
17 
18 return $response->exitStatus;
19 } catch (ExitException $e) {
20 $this->end($e->statusCode, isset($response) ? $response : null);
21 return $e->statusCode;
22 }
23 }

这个方法里包含了从初始化beforeRequest事件,到afterRequest的全部程序,可谓是核心方法。

那么我们来看一下,都有些什么?

首先,执行beforeRequest绑定的事件,指定web应用运行状态。

后者,处理请求url和参数。

再者,解析路由,实例化controller类、action类。

而后,执行beforeAction事件和处理action程序、afterAction事件。

最后,执行afterRequest事件,实例response指定data,响应客户端。

好了,因为时间关系,此次就解析这么多。若有建议和不一样意见,请关注博客,敬请留言。

相关文章
相关标签/搜索