yii2深入理解之内核解析
一、前言
首先,yii2最为为数不多的PHP主流开源框架,受欢迎程度不亚于laravel和TP。个人认为,研究这些框架底层代码是非常有助于自身代码编程思想的提升和代码简化程度和质量的提升的。
那么,话不多说,下面开始说一下自己对yii2底层框架架构的理解。
二、客户端请求处理
yii2对客户请求处理,提供了url美化类urlManager,这点在最初通过composer加载,并初始化框架时,已经在config目录下的main文件里生成了, 只不过时注释过的,如果需要url美化则取消掉注释即可。其实,yii2对apache的支持是非常的好的。
说到这了,那么我们就说一下,后端最流行的两个服务器,apache和nginx的区别。
a、nginx性能比apache要好很多,相比apache,但bug就会相对多。
b、nginx相比apache轻量级了不少,配置也相对简单,而且,对高并发的请求事件处理,可以是异步非阻塞的处理请求,能消耗低。
c、apache相比nginx,它的重写能力要比nginx强很多,而且,功能模块比nginx多很多,其性能比nginx稳定,bug较少。
所以说,yii2的url美化组件urlManager对apache服务器有很好的支持。
框架和项目配置,我们可以直接在common文件下的config文件下的main-local文件里配置,数据库的连接以及数据表的前缀等。web文件夹下的.htaccess文件内容如下:
- Header always set Access-Control-Allow-Origin "*"
- Header always set Access-Control-Allow-Headers: "X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding"
- RewriteEngine ON
- RewriteCond %{REQUEST_FILENAME} !-f
- RewriteCond $1 !^(index\.php|robots\.txt|favicon\.ico|Sitemap\.xml|pma)
- RewriteRule ^(.*)$ index.php/$1 [L]
- php_value upload_max_filesize "50M"
- php_value post_max_size "50M"
- php_value max_execution_time "40000"
- 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,图片等;
三、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,响应客户端。
好了,由于时间关系,这次就解析这么多。如有建议和不同意见,请关注博客,敬请留言。
yii2深入理解之内核解析的更多相关文章
- 深入理解php内核 编写扩展 I:介绍PHP和Zend
内容: 编写扩展I - PHP和Zend起步 原文:http://devzone.zend.com/public/view/tag/Extension Part I: Introduction to ...
- 读书笔记之Linux系统编程与深入理解Linux内核
前言 本人再看深入理解Linux内核的时候发现比较难懂,看了Linux系统编程一说后,觉得Linux系统编程还是简单易懂些,并且两本书都是讲Linux比较底层的东西,只不过侧重点不同,本文就以Linu ...
- 《深入理解Android内核设计思想》
<深入理解Android内核设计思想> 基本信息 作者: 林学森 出版社:人民邮电出版社 ISBN:9787115348418 上架时间:2014-4-25 出版日期:2014 年5月 开 ...
- 深入理解PHP内核(九)变量及数据类型-静态变量
原文链接:http://www.orlion.ga/251/ 通常静态变量是静态分配的,他们的生命周期和程序的生命周期一样长,只有在程序退出后才结束生命周期,这和局部变量相反,有的语言中全局变量也是静 ...
- 深入理解PHP内核(二)概览-PHP生命周期与Zend引擎
本文参考自<深入理解PHP内核>,地址:https://github.com/reeze/tipi 本文链接:http://www.orlion.ml/232/ 1.SAPI接口 SAPI ...
- c#网络通信框架networkcomms内核解析 序言
NetworkComms网络通信框架序言 networkcomms是我遇到的写的最优美的代码,很喜欢,推荐给大家:) 基于networkcomms2.3.1开源版本( gplv3)协议,写了一些文章, ...
- c#网络通信框架networkcomms内核解析之十 支持优先级的自定义线程池
NetworkComms网络通信框架序言 本例基于networkcomms2.3.1开源版本 gplv3协议 如果networkcomms是一顶皇冠,那么CommsThreadPool(自定义线程池 ...
- c#网络通信框架networkcomms内核解析之八 数据包的核心处理器
NetworkComms网络通信框架序言 本文基于networkcomms2.3.1开源版本 gplv3协议 我们先回顾一个 c#网络通信框架networkcomms内核解析之六 处理接收到的二进制 ...
- 推荐一本书《深入理解PHP内核》
<深入理解PHP内核> 在线网址:http://www.php-internals.com/
随机推荐
- windows常用命令行总结
cmd下的命令行 1.查看当前目录下的子目录 dir 或 dir /b 类似Linux 下的 ls 或者 ls -l 2.盘符切换 d: 3.进入目录 cd [目录名] 退一个目录 cd .. ...
- 连接Mysql时出现java.math.BigInteger cannot be cast to java.lang.Long问题
今天遇见这样一个坑.在连接数据库进行查询数据时,大家可能会遇见这样一个问题:java.math.BigInteger cannot be cast to java.lang.Long,然后去检查代码中 ...
- Hibernate课程 初探一对多映射5-2 Eclipse添加数据库连接
1 Eclipse新建java项目 2 Windows ==> show view == >other ==>Data source Explorer 3 左侧视图 database ...
- 轻松完成excel读写操作- 基于POI的框架BingExcel的使用(2)
在进行 类转换时候,系统默认注册了一些转换器,当然你也可以自定局部或者全局的转换器.下面进行具体使用说明 java类说明 对应的java实体类,其属性必须要有__@CellConfig__注解,此注 ...
- 转:用AutoCAD 系统变量编程
Autocad的系统变量, 我们可以通过如下得到: Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable(/*MSG0* ...
- unity工具介绍
MemoryProfiler内存分析工具 行为树 behaviac github 场景动画编辑器 Snapdragon Profiler性能分析工具 VTune性能分析器 protobuf数据交换格式 ...
- Javascript基础--函数(Function对象)
1.函数是一段可执行的代码,函数可多次调用,模块化管理. 2.使用function语句,function funName([arg1][,arg2]....[,argn]){代码块}.所有版本可用,一 ...
- mybatis学习目录
mybatis详解动态SQL https://www.cnblogs.com/ysocean/p/7289529.html mybatis查询时间段sql语句 http://www.cnblogs.c ...
- Eclipse导入web项目后,run列表中没有run on server?
Eclipse导入web项目,没有run列表中run on server? 首先确保正确安装Tomcat和JDK .找到对于web项目的文件夹,打开文件夹下.project文件 <?xml ve ...
- 03、IDEA下Spark API编程
03.IDEA下Spark API编程 3.1 编程实现Word Count 3.1.1 创建Scala模块 3.1.2 添加maven支持,并引入spark依赖 <?xml version=& ...