我是在  backend 一步步打印的   很多地方我也是很模糊 。后来发现一位大神的文章(http://www.yiichina.com/tutorial/773)  参考文章自己动手开始写的  至于后来的 第一遍 很粗糙 慢慢完善。
希望对自己有帮助 希望各位积极指点 和后面不详细的地方 作补充。 我也会继续完善 。 先从入口开始
$application = new yii\web\Application($config);  //实例化 Application
$application->run();
这是  Application 的方法
class Application extends \yii\base\Application   
在Application类中 首先看有没有构造方法  没有找到  so  就去父类中找(\yii\base\Application)

在\yii\base\Application  
..........
public function __construct($config = [])
{
Yii::$app = $this;  // $this 代表 object(yii\web\Application)
static::setInstance($this);  // 在这个方法中把这个类中所有的方法属性都放到一个数组中@@@@@请看下面 $this->state = self::STATE_BEGIN; $this->preInit($config);  //看下面有解释 $this->registerErrorHandler($config);//暂不做解释 加载异常类 以后研究   Component::__construct($config);
}
..........
@@@@@
public static function setInstance($instance)
{
if ($instance === null) {    //$instance不为空 代表的$this(object(yii\web\Application))
        unset(Yii::$app->loadedModules[get_called_class()]);
} else {              //get_class($instance) -> "yii\web\Application"
Yii::$app->loadedModules[get_class($instance)] = $instance;
}
}
这样 Yii::$app 就可以调用 该类中的方法 属性 以及父类中的方法。

$this->preInit($config);//

*****preInit****方法

主要是获取到配置文件中的数据  处理配置文件的数据 设置别名等等
public function preInit(&$config)
{
if (!isset($config['id'])) {
throw new InvalidConfigException('The "id" configuration for the Application is required.');
}
if (isset($config['basePath'])) {
$this->setBasePath($config['basePath']); //拿这个做例子
unset($config['basePath']); 。。。部分代码省略。。。。。
  
  public function setBasePath($path)
  {              
      var_dump($path);die;   //     "/var/www/testyii2/backend"     
   parent::setBasePath($path);     //该方法中设置 $this->_basePath = $app;  $app=/var/www/testyii2/backend
      Yii::setAlias('@app', $this->getBasePath());   so  此时  @app  就等于  /var/www/testyii2/backend
  }
好了现在回到 preInit()方法中
*******end*****
$this->registerErrorHandler($config);简单看下吧
$this->set('errorHandler', $config['components']['errorHandler']);
我打印了下 var_dump($this->get('errorHandler')) 应该是 定义一些错误方法和属性等等 看下图


最后看这个方法
Component::__construct($config);  调用了 object 方法中的 构造方法
object(类):
public function __construct($config = [])
{
if (!empty($config)) {
Yii::configure($this, $config);  //找到Yii类 该类中没有configure 方法 然而继承了 baseyii so 去baseyii类中找
                          //
}
$this->init();
}
。。。。。
//baseyii类
public static function configure($object, $properties)
{
foreach ($properties as $name => $value) {
$object->$name = $value;
}
return $object;
}
//该方法 中 $object ==object类 循环吧配置文件中的 数据 复制给 object对象中的属性和值  最终由于object 是yii\web\Application 的最终父类 还有在上面中定义了别名@app

  // so  可以Yii::$app->配置参数来访问配置文件中的内容

****end***

分析
$this->init();  在object类中   class Component extends Object  component继承的object
Component::__construct($config);   在base/Application  继承了 Module 类 
so 看module 中的init方法()
//module 中的init 方法
public function init()
{
if ($this->controllerNamespace === null) {  //取出控制器命名空间。
$class = get_class($this);
if (($pos = strrpos($class, '\\')) !== false) {
$this->controllerNamespace = substr($class, 0, $pos) . '\\controllers';
}
}
}

完毕

回到起点 看index.php中的

$application->run();   在Application类中没有找到run方法   Application 继承 base\Application类

\yii\base\Application.php   中的run方法

    public function run()
{
try { $this->state = self::STATE_BEFORE_REQUEST;
$this->trigger(self::EVENT_BEFORE_REQUEST);  ////加载事件函数函数的 $this->state = self::STATE_HANDLING_REQUEST;
$response = $this->handleRequest($this->getRequest());  //这里的this调用的是 yii\web\Application.php 中的方法看下面
        $this->state = self::STATE_AFTER_REQUEST;
$this->trigger(self::EVENT_AFTER_REQUEST); //加载事件函数函数的
        $this->state = self::STATE_SENDING_RESPONSE; $response->send(); 

      $this->state = self::STATE_END; return $response->exitStatus; }
    catch (ExitException $e) {
         $this->end($e->statusCode, isset($response) ? $response : null); return $e->statusCode; }
      }
//web/Application 中的 handleRequest()
public function handleRequest($request)
{
if (empty($this->catchAll)) {
list ($route, $params) = $request->resolve();  //取出路由及参数
} else {
$route = $this->catchAll[0];
$params = $this->catchAll;
unset($params[0]);
}
try {
Yii::trace("Route requested: '$route'", __METHOD__);
$this->requestedRoute = $route;
$result = $this->runAction($route, $params);//运行控制器中的Acition,下面有详细介绍 base/application 中没有so 找到module 中的runaction()
if ($result instanceof Response) {
return $result;
} else {
$response = $this->getResponse();
if ($result !== null) {
$response->data = $result;
} return $response;
}
} catch (InvalidRouteException $e) {
throw new NotFoundHttpException(Yii::t('yii', 'Page not found.'), $e->getCode(), $e);
}
}
// class Module

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);//创建方法执行控制器里的action actionId ==index( 控制器/index(这里表示方法))
Yii::$app->controller = $oldController; return $result;
} else {
$id = $this->getUniqueId();
throw new InvalidRouteException('Unable to resolve the request "' . ($id === '' ? $route : $id . '/' . $route) . '".');
}
}
$this->createController()
$this->createController()  //创建控制器
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 = '';
}
echo   $route //--->"backend/default/index"
// module and controller map take precedence
    if (isset($this->controllerMap[$id])) {  //不进入
$controller = Yii::createObject($this->controllerMap[$id], [$id, $this]);
return [$controller, $route];
}
$module = $this->getModule($id);
if ($module !== null) {        //不进入
return $module->createController($route);
} if (($pos = strrpos($route, '/')) !== false) {
$id .= '/' . substr($route, 0, $pos);  
$route = substr($route, $pos + 1);  
}
//$id = backend/default"   (模块/控制器)   $route =index   方法
    $controller = $this->createControllerByID($id);  //下面分析用颜色查找
if ($controller === null && $route !== '') {  //进入
$controller = $this->createControllerByID($id . '/' . $route); // 根据给定的控制器标识创建一个控制器。看下面
$route = '';
} return $controller === null ? false : [$controller, $route];
}
 
public function createControllerByID($id)
{
$pos = strrpos($id, '/');
if ($pos === false) {
$prefix = '';
$className = $id;
} else {
$prefix = substr($id, 0, $pos + 1);    //backend 模块
$className = substr($id, $pos + 1);    //default 控制器
} if (!preg_match('%^[a-z][a-z0-9\\-_]*$%', $className)) {
return null;
}
// preg_match('%^[a-z0-9_/]+$%i', $prefix) ===1
    if ($prefix !== '' && !preg_match('%^[a-z0-9_/]+$%i', $prefix)) {      
        return null;
}
    $className = str_replace(' ', '', ucwords(str_replace('-', ' ', $className))) . 'Controller';  
$className = ltrim($this->controllerNamespace . '\\' . str_replace('/', '\\', $prefix) . $className, '\\');
if (strpos($className, '-') !== false || !class_exists($className)) {
return null;
}
  
if (is_subclass_of($className, 'yii\base\Controller')) {
$controller = Yii::createObject($className, [$id, $this]);  //创建了控制器对象
return get_class($controller) === $className ? $controller : null;
} elseif (YII_DEBUG) {
throw new InvalidConfigException("Controller class must extend from \\yii\\base\\Controller.");
} else {
return null;
}
}
Yii/BaseYii.php
public static function createObject($type, array $params = [])
{
if (is_string($type)) {
return static::$container->get($type, $params);  //返回请求类的是例 这边就不往下追了 本人能力有限啊 唉~无线惆怅中~~~
} elseif (is_array($type) && isset($type['class'])) {
$class = $type['class'];
unset($type['class']);
return static::$container->get($class, $params, $type);
} elseif (is_callable($type, true)) {
return static::$container->invoke($type, $params);
} elseif (is_array($type)) {
throw new InvalidConfigException('Object configuration must be an array containing a "class" element.');
} else {
throw new InvalidConfigException('Unsupported configuration type: ' . gettype($type));
}
}
****end** 小部分结束(创建控制器部分)
//承接上面的方法继续分析
$controller->runAction($actionID, $params);
namespace  yii\base;   //命名空间
class Controller extends Component implements ViewContextInterface{
public function runAction($id, $params = [])
{
  $action = $this->createAction($id);  ////创建action  暂时不补全代码了 类啊。。。后续补上。
  //打印$action == yii\base\InlineAction 对象

   if ($action === null) {
  throw new InvalidRouteException('Unable to resolve the request: ' . $this->getUniqueId() . '/' . $id);
  }   Yii::trace("Route to run: " . $action->getUniqueId(), __METHOD__);   if (Yii::$app->requestedAction === null) {
   Yii::$app->requestedAction = $action;
  }   $oldAction = $this->action;    //NULL
  $this->action = $action;   $modules = [];
  $runAction = true;   // call beforeAction on modules   // 加载默认模块如:Application log等。再调用模块内的beforeAction方法
  foreach ($this->getModules() as $module) {
   if ($module->beforeAction($action)) {
   array_unshift($modules, $module);
   } else {
   $runAction = false;
   break;
   }
  } $result = null; if ($runAction && $this->beforeAction($action)) { //执行beforeAction
// run the action
$result = $action->runWithParams($params);   //执行控制器里的action $result = $this->afterAction($action, $result); //执行afterAction

    // call afterAction on modules
foreach ($modules as $module) {
/* @var $module Module */
$result = $module->afterAction($action, $result);
}
} $this->action = $oldAction; return $result;
}
}

//打印action  yii\base\InlineAction
public function runWithParams($params)
{
$args = $this->controller->bindActionParams($this, $params);
Yii::trace('Running action: ' . get_class($this->controller) . '::' . $this->actionMethod . '()', __METHOD__);
if (Yii::$app->requestedParams === null) {
Yii::$app->requestedParams = $args;
} return call_user_func_array([$this->controller, $this->actionMethod], $args);
}

yii2 源码分析1从入口开始的更多相关文章

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

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

  2. Yii2源码分析(一):入口

    写在前面,写这些随笔是记录下自己看Yii2源码的过程,可能会有些流水账,大部分解析放在注释里说明,由于个人水平有限,有不正确的地方还望斧正. web入口文件Index.php // 定义全局的常量,Y ...

  3. MongoDB源码分析——mongo主程序入口分析

    Edit   源码版本为MongoDB 2.6分支 mongo主程序入口分析 mongo是MongoDB提供的一个执行JavaScript脚本的客户端工具,可以用来和服务端交互,2.6版本的Mongo ...

  4. MYC编译器源码分析之程序入口

    前文.NET框架源码解读之MYC编译器讲了MyC编译器的架构,整个编译器是用C#语言写的,上图列出了MyC编译器编译一个C源文件的过程,编译主路径如下: 首先是入口Main函数用来解析命令行参数,读取 ...

  5. yii2 源码分析 object类分析 (一)

    转载请注明链接http://www.cnblogs.com/liuwanqiu/p/6737327.html yii2基本上所有的类都是继承的object类,下面就来分析一下object类吧 obje ...

  6. yii2 源码分析 model类分析 (五)

    模型类是数据模型的基类.此类继承了组件类,实现了3个接口 先介绍一下模型类前面的大量注释说了什么: * 模型类是数据模型的基类.此类继承了组件类,实现了3个接口 * 实现了IteratorAggreg ...

  7. yii2 源码分析Action类分析 (六)

    Action类是控制器的基类, <?php namespace yii\base; use Yii; /** * Action是所有控制器动作类的基类,它继承组件类 * * 动作提供了重用动作方 ...

  8. yii2 源码分析Behavior类分析 (四)

    Behavior类是所有事件类的基类,它继承自object类 Behavior类的前面注释描述大概意思: * Behavior类是所有事件类的基类 * * 一个行为可以用来增强现有组件的功能,而不需要 ...

  9. yii2 源码分析Event类分析 (三)

    转载请注明链接:http://www.cnblogs.com/liuwanqiu/p/6739880.html Event是所有事件的基类,它继承Object类 Event类上面的注释的大致意思: * ...

随机推荐

  1. Golang调用windows下的dll动态库中的函数

    Golang调用windows下的dll动态库中的函数 使用syscall调用. package main import ( "fmt" "syscall" & ...

  2. java网络编程TCP传输—流操作—拿到源后的写入动作

    在网络编程中的TCP传输里,拿到Socket的源后,应该怎么进行读写操作呢,下面我列举了两种方法,希望大家帮忙补充···· 1.利用byte数组作为一个缓冲区进行读写 客户端上传 //获取socket ...

  3. 5,基于关系和超链接的 API

    Tutorial 5: Relationships & Hyperlinked APIs At the moment relationships within our API are repr ...

  4. UVA12296 Pieces and Discs

    题意 PDF 分析 可以看成直线切割多边形,直接维护. 对每个多边形考虑每条边和每个点即可. 时间复杂度?不过\(n,m \leq 20\)这种数据怎么都过了.据说是\(O(n^3)\)的,而且常数也 ...

  5. debezium 数据变更工具使用

    1.  作用 简单概述就是CDC(change data capture),实时数据分析领域用的比较多   2. 简单使用(基于官网的docker 说明)  备注: 测试没有使用守护进程模式为了方便测 ...

  6. (转)【Android】获取Mac地址【2】

    [Android]获取Mac地址[2] 之前写了[Android]获取Mac地址[1]有些不够详细,现在贴上一些其他代码,仅供参考. (1) 调用android 的API: NetworkInterf ...

  7. java md5 函数

    private static final String md5(final String s) { final String MD5 = "MD5"; try { // Creat ...

  8. erlang的dict和maps模块

    erlang在r17以后增加了map这个数据结构,在之前,类似map的需求用dict模块来实现,这里直接贴一下相关的操作 dict D = dict:new(). D1 = dict:store(k1 ...

  9. (转)WebApi发送HTML表单数据:文件上传与多部分MIME

    5.3 Sending HTML Form Data5.3 发送HTML表单数据(2) 本文引自:http://www.cnblogs.com/r01cn/archive/2012/12/20/282 ...

  10. 【转】JMeter Tutorial的安装和具体操作

    1.下载Jmeter 下载地址:http://jmeter.apache.org/download_jmeter.cgi 目前最新版为2.9,其余文件如源代码等也可从如下官网下载: http://jm ...