yii2 beta版 执行流程

自动加载

1.composer的自动加载

	//composer的加载实现了四种方式,可以看看
require(__DIR__ . '/../../vendor/autoload.php');

composer的自动加载只加载其下载的组件....和yii框架的加载没有任何关系 2.yii的加载

	spl_autoload_register(['Yii', 'autoload'], true, true);
Yii::$classMap = include(__DIR__ . '/classes.php');
Yii::$container = new yii\di\Container;

这里使用spl_autoload_register把Yii::autoload注册成自动加载器,

  • 判断在不在$classMap中,如果有别名获取别名的文件路径
  • 如果不在$classMap中,则去除下划线,使用别名获取文件路径
  • 引入该文件,并判断是不是类或者接口或者trait
	public static function autoload($className)
{
if (isset(static::$classMap[$className])) {
$classFile = static::$classMap[$className];
if ($classFile[0] === '@') {
$classFile = static::getAlias($classFile);
}
} elseif (strpos($className, '\\') !== false) {
$classFile = static::getAlias('@' . str_replace('\\', '/', $className) . '.php', false);
if ($classFile === false || !is_file($classFile)) {
return;
}
} else {
return;
} include($classFile); if (YII_DEBUG && !class_exists($className, false) && !interface_exists($className, false) && !trait_exists($className, false)) {
throw new UnknownClassException("Unable to find '$className' in file: $classFile. Namespace missing?");
}
}

Yii::$classMap中保存的是命名空间和文件实际路径的对应表,默认加载了所有yii提供的类 Yii::$container 实现了依赖注入, Yii::$app 继承serviceLocal..只实现了单例组件,其中属性_components保存的是对象,_definitions保存的是类,匿名函数或者对象

引导前初始化配置

1.检查配置中模块ID是不是存在
2.检查配置中basePath,vendorPath,runtimePath,timeZone是否存在,并设置
3.向配置中添加核心组件配置:
base:log,view,formatter,i18n,mailer,urlManager,assetManager,security
web:request,response,session,user,errorHandler

4.如果启用了YII_ENABLE_ERROR_HANDLER错误处理,则会注册错误处理组件.然后从配置中卸载errorHandler,避免之后的引导再次添加组件.

	    ini_set('display_errors', false);  //注意这里...
set_exception_handler([$this, 'handleException']);
set_error_handler([$this, 'handleError']);
if ($this->memoryReserveSize > 0) {
$this->_memoryReserve = str_repeat('x', $this->memoryReserveSize);
}
register_shutdown_function([$this, 'handleFatalError']);

5.然后将配置中的值赋给applicaition

属性 说明 所在文件
$_events 使用on xxx 开通注册事件 yii\base\Component
$_behaviors 使用 as xxx开头注册行为 yii\base\Component
$_components 保存组件单例对象 yii\di\ServiceLocator
$_definitions 保存组件的原始数据 yii\di\ServiceLocator
$params 参数,是个数组 yii\base\Module
$id 模块ID yii\base\Module
$module 该模块的父模块 yii\base\Module
$layout 布局 yii\base\Module
$controllerMap 控制器地图 yii\base\Module
$controllerNamespace 控制器命名空间 yii\base\Module
$defaultRoute 默认路由 yii\base\Module
$_basePath 模块的根目录 yii\base\Module
$_viewPath 模块的视图目录 yii\base\Module
$_layoutPath 模块的布局目录 yii\base\Module
$_modules 子模块 yii\base\Module
$_instances 这个不常用,获取当前请求模块的实例 yii\base\Module
$controllerNamespace 'app\\controllers' yii\base\Application
$name 应用名称 yii\base\Application
$version 版本 yii\base\Application
$charset 字符编码.默认utf8 yii\base\Application
$language 语言,默认en-US yii\base\Application
$sourceLanguage 源语言 yii\base\Application
$controller 当前的控制器实例 yii\base\Application
$layout 布局 yii\base\Application
$requestedRoute 请求的路由 yii\base\Application
$requestedAction 请求的动作 yii\base\Application
$requestedParams 请求的参数 yii\base\Application
$extensions 扩展 yii\base\Application
$bootstrap 引导 yii\base\Application
$state 状态 yii\base\Application
$defaultRoute 默认路由 yii\web\Application
$catchAll 捕捉所有 yii\web\Application
$controller 当前控制器实例 yii\web\Application

引导阶段

  • 1.初始化request组件
  • 2.设置@webroot和@web别名
  • 3.加载扩展extensions,如果没有设置extensions会读取@vendor/yiisoft/extensions.php中的扩展并设置别名,如果扩展可引导,则执行其bootstrap方法-----本身来讲扩展概念没什么用处,因为还是依靠modules来加载这些扩展
  • 4.加载bootstrap中设置的组件和模块或者类,如果引导类实现了BootstrapInterface接口则执行bootstrap的方法

运行

  • 触发请求前事件EVENT_BEFORE_REQUEST,yii-debug中注册了该事件
  • 处理请求,如果catchAll不为空,则使用里面的路由.否则的话会解析获得路由和参数,
    然后执行动作action,返回响应Response,或者响应的data数据.

    		public function handleRequest($request)
    {
    if (empty($this->catchAll)) {
    list ($route, $params) = $request->resolve();
    } else {
    $route = $this->catchAll[0];
    $params = array_splice($this->catchAll, 1);
    }
    try {
    Yii::trace("Route requested: '$route'", __METHOD__);
    $this->requestedRoute = $route;
    $result = $this->runAction($route, $params);
    if ($result instanceof Response) {
    return $result;
    } else {
    $response = $this->getResponse();
    if ($result !== null) {
    $response->data = $result;
    } return $response;
    }
    } catch (InvalidRouteException $e) {
    throw new NotFoundHttpException($e->getMessage(), $e->getCode(), $e);
    }
    }
  • 动作的执行:首先会根据路由创建控制器.然后执行动作.
        public function runAction($route, $params = [])
    {
    $parts = $this->createController($route);
    if (is_array($parts)) {
    /* @var $controller Controller */
    list($controller, $actionID) = $parts;
    $oldController = Yii::$app->controller;
    Yii::$app->controller = $controller;
    $result = $controller->runAction($actionID, $params);
    Yii::$app->controller = $oldController; return $result;
    } else {
    $id = $this->getUniqueId();
    throw new InvalidRouteException('Unable to resolve the request "' . ($id === '' ? $route : $id . '/' . $route) . '".');
    }
    }

    创建控制器

    	public function createController($route)
    {
    //路由为空则使用默认路由
    if ($route === '') {
    $route = $this->defaultRoute;
    } // double slashes or leading/ending slashes may cause substr problem
    $route = trim($route, '/');
    if (strpos($route, '//') !== false) {
    return false;
    } //分解路由...前两个第一个可能是模块..第二个才是控制器
    if (strpos($route, '/') !== false) {
    list ($id, $route) = explode('/', $route, 2);
    } else {
    $id = $route;
    $route = '';
    } // module and controller map take precedence
    $module = $this->getModule($id);
    if ($module !== null) {
    //如果有模块,则继续往下面找.这里是递归...能一直查询子模块
    return $module->createController($route);
    } //查看控制器地图...一般控制器地图里的控制器..作为产品临时使用的页面
    if (isset($this->controllerMap[$id])) {
    $controller = Yii::createObject($this->controllerMap[$id], [$id, $this]); return [$controller, $route];
    } //执行到最后,没有子模块的时候...则将id加上剩余的路径(可能有多个/文件夹)
    if (($pos = strrpos($route, '/')) !== false) {
    $id .= '/' . substr($route, 0, $pos);
    $route = substr($route, $pos + 1);
    } $controller = $this->createControllerByID($id);
    if ($controller === null && $route !== '') {
    $controller = $this->createControllerByID($id . '/' . $route);
    $route = '';
    } return $controller === null ? false : [$controller, $route];
    }

    获取模块

    	public function getModule($id, $load = true)
    {
    //这一段是获取子模块的..在运行中是没有作用的..这一小部分可以当方法使用..
    if (($pos = strpos($id, '/')) !== false) {
    // sub-module
    $module = $this->getModule(substr($id, 0, $pos)); return $module === null ? null : $module->getModule(substr($id, $pos + 1), $load);
    } //这是返回模块
    if (isset($this->_modules[$id])) {
    if ($this->_modules[$id] instanceof Module) {
    return $this->_modules[$id];
    } elseif ($load) {
    Yii::trace("Loading module: $id", __METHOD__);
    if (is_array($this->_modules[$id]) && !isset($this->_modules[$id]['class'])) {
    $this->_modules[$id]['class'] = 'yii\base\Module';
    }
    /* @var $module Module */
    $module = Yii::createObject($this->_modules[$id], [$id, $this]);
    $module->setInstance($module);
    return $this->_modules[$id] = $module;
    }
    } return null;
    }
  • 触发请求后事件EVENT_AFTER_REQUEST,yii未注册事件
  • 响应发送

yii2 beta版 执行流程的更多相关文章

  1. {Django基础九之中间件} 一 前戏 二 中间件介绍 三 自定义中间件 四 中间件的执行流程 五 中间件版登陆认证

    Django基础九之中间件 本节目录 一 前戏 二 中间件介绍 三 自定义中间件 四 中间件的执行流程 五 中间件版登陆认证 六 xxx 七 xxx 八 xxx 一 前戏 我们在前面的课程中已经学会了 ...

  2. Yii2 源码分析 入口文件执行流程

    Yii2 源码分析  入口文件执行流程 1. 入口文件:web/index.php,第12行.(new yii\web\Application($config)->run()) 入口文件主要做4 ...

  3. [App Store Connect帮助]六、测试 Beta 版本(1)TestFlight Beta 版测试概述(iOS、Apple TVOS、watchOS)

    TestFlight Beta 版测试让您可以分发您 App 的 Beta 版构建版本给测试员并收集反馈.您可以在您的 App Store Connect 帐户中一次为至多 100 个 App 启用 ...

  4. Ubuntu 安装yii2 advanced版 遇到的坑

    1.安装 Composer https://www.yiichina.com/doc/guide/2.0/start-installation通过 Composer 安装 curl -sS https ...

  5. Mysql漂流系列(一):MySQL的执行流程

    MySQL的执行流程 MySQL的执行流程: MySQL的执行流程分析: 1.当我们请求mysql服务器的时候,MySQL前端会有一个监听,请求到了之后,服务器得到相关的SQL语句,执行之前(虚线部分 ...

  6. yii2 advanced版基础部分

    yii2 advanced版 一.目录结构 1.backend 和 frontend : 前后台入口,相当于是一个单独的Basic应用,有自己的 mvc 目录.配置文件目录.入口文件目录 2.cons ...

  7. Beta版测试报告

    Beta版测试报告 测试中发现的Bug: Version 2.0 Bug List 1. 在动态监测界面,若随便点击“开始”.“关闭”.“结束”.红叉,会出现不定式崩溃现象. 2. 处理空数据时可能会 ...

  8. Dalvik虚拟机java方法执行流程和Method结构体分析

    Method结构体是啥? 在Dalvik虚拟机内部,每个Java方法都有一个对应的Method结构体,虚拟机根据此结构体获取方法的所有信息. Method结构体是怎样定义的? 此结构体在不同的andr ...

  9. linux下无线鼠标驱动执行流程

    操作系统: debian 7.4(linux 3.2.54) 硬件: 一个无线鼠标.一个有线鼠标.usb集线器. 从淘宝上花了15块钱买了个无线鼠标,很好奇它的驱动程序是如何执行的. 首先将usb集线 ...

随机推荐

  1. Struts2典型应用

    1. Struts2处理表单数据 例1.1 创建Java Web项目,编写一个Action对象,处理对表单提交的数据,模拟实现对指定用户的问候. (1)创建Java Web项目,将Struts的支持类 ...

  2. GOOGLE突破图书馆入口IP限制之技巧

    很多图书馆都要注册或要本地IP才能浏览或下载图书,有没有另类的快速办法能快速突破图书馆的入口,能随意地下载图书呢? 希望大家在GOOGLE里试试这个:“index of/ ” inurl:lib 你将 ...

  3. mac下的一些命令

    1.显示隐藏文件 defaults write com.apple.finder AppleShowAllFiles -bool true 2.隐藏隐藏文件 defaults write com.ap ...

  4. Python开发之AJAX全套

    概述 对于WEB应用程序:用户浏览器发送请求,服务器接收并处理请求,然后返回结果,往往返回就是字符串(HTML),浏览器将字符串(HTML)渲染并显示浏览器上. 1.传统的Web应用 一个简单操作需要 ...

  5. Morton Code

    莫顿码 ,实现了一维与二维(或多维)的转换.它通过交叉存储两个数的位产生一个数,即莫顿码. 可以应用于为一个整数对产生一个唯一索引. 例如,对于坐标系中的坐标点使用莫顿编码生成的莫顿码,可以唯一索引对 ...

  6. (转)akka Router实例

    通常在分布式任务调度系统中会有这样的需求:一组actor提供相同的服务,我们在调用任务的时候只需要选择其中一个actor进行处理即可. 其实这就是一个负载均衡或者说路由策略,akka作为一个高性能支持 ...

  7. [简谈]绕过HR破门而入的求职智慧

    以往我们在网上看到的非常多求职文章或指导性纲领,譬如啥自信.做功课.良好形象.华丽的简历.工作经验.口才啥的,事实上到了21世纪尤其是互联网快速发展的今天,前面这些技巧就显得无比空洞: 1.由于自信谁 ...

  8. (剑指Offer)面试题56:链表中环的入口结点

    题目: 一个链表中包含环,请找出该链表的环的入口结点. 思路: 1.哈希表 遍历整个链表,并将链表结点存入哈希表中(这里我们使用容器set),如果遍历到某个链表结点已经在set中,那么该点即为环的入口 ...

  9. .NET破解之爱奇迪(一)

    今天无意中看到了wuhuacong(伍华聪)的专栏,界面写得还是很炫的感觉,于是在广州爱奇迪官网下载一个来试一下——客户关系管理系统.下面是成果: 00.总体把握 里面有Logon窗口(为什么不是Lo ...

  10. 工具篇:使用natapp工具映射内网到外网访问

    一.环境说明 开发基于微信公众号的应用最大的痛苦之处就是调试问题,每次实现一个功能后都需要部署到一个公网服务器进行测试,因为微信用户每次向公众号发起请求时,微信服务器会先接收到用户的请求,然后再转发到 ...