Laravel框架执行流程
2017-08-21 16:05
183 查看
俗话说知己知彼百战不怠,使用Laravel也有有一段时间了,中间也踩了很多坑,碰了很多壁,归根结底还是对Laravel的底层不太了解,以前使用Thinkphp养成的MVC的习惯,刚接触Laravel一时还没转变过来,所以最近抱着学习的态度,研究了下Laravel框架的执行流程。
Laravel虽然使用上感觉跟Thinkphp差不多,但是底层的实现方式还有框架的架构,跟Thinkphp差别还是蛮大,不过Tp5貌似吸收了很多Laravel中的特性。
废话到此为止,下面上干货
创建容器$app
2
3
4
1
2
3
4
该类是框架核心类,负责启动框架,以及调动其他类提供的功能。
该类继承了Illuminate\Container\Container类,可见该类也是个容器。是整个框架最大的容器;
该类的构造器代码如下:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
设置接口类的实现类,并使用单例模式实例化实现类。
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
获得Http内核Kernel的示例
2
1
2
http内核黑箱操作,接收request参数,返回一个response。这一步完整个程序的所有操作,形成一个完成的http请求,至于该请求的具体处理,则有kernel内部调度。这里是重点所在。
Http响应,发送Http响应头以及响应内容,代码如下:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
结束所有中间件以及可终止程序
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
加载框架类库,创建容器,接收request请求。
以管道的设计模式 执行部分中间件
路由解析调度
实例化当前控制器
执行web中间件
执行控制器中间件
执行控制器操作
返回response
接收框架
以前很公共的东西都习惯放在控制器基类的构造函数中,但是在lavarvel5.3以后却不能这么做了,因为由上述执行流程可以看出,web中间件在控制器实例化之后才执行,所以在控制器构造函数执行是session还没有初始化,即在控制器构造函数中获得不了session数据。所以也就获得不了当前用户。所以导致很多操作都做不了了。但是laravel提供了可插拔形式的中间件很好的解决了这个问题。自定义中间件在web中间件之后,Action之前执行。所以很多之前放在构造函数里的操作都可以放在中间件里解决。
laravel框架中使用了大量的static:: (后期静态绑定),单独看代码很难知道调用的函数时那个类的。只有在用运行的时候,才会动态计算出,调用的是那个类的函数。如下面代码:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
这段代码来自 Illuminate\Support\Facades这个类。该类是一个抽象类。我们用的非常多的一个类Auth就是集成该类。
我们都知道Auth中有很多静态函数,如:Auth::check(),Auth::user(),Auth::guest()等等,但是当我们打开Auth类的时候,发现里面并没有这些方法,而他的父类facades中也没有这些方法。只有这个__callStatic函数。从名称不难看出,这是一个静态类的魔术方法。调用所有不存在的静态方法都会调用改函数。
从该函数的实现不难看出,该函数很像是一个工厂函数,获得当前调用函数的实例化对象,然后再调用该函数。 该函数就想是单入口的web程序的入口文件,
Laravel虽然使用上感觉跟Thinkphp差不多,但是底层的实现方式还有框架的架构,跟Thinkphp差别还是蛮大,不过Tp5貌似吸收了很多Laravel中的特性。
废话到此为止,下面上干货
1. 入口文件index.php
1. 引入bootstrap/autoload.php,自动加载依赖库
2. 引入bootstrap/app.php’
创建容器$app// 参数为应用程序根目录 $app = new Illuminate\Foundation\Application( realpath(__DIR__.'/../') );1
2
3
4
1
2
3
4
该类是框架核心类,负责启动框架,以及调动其他类提供的功能。
该类继承了Illuminate\Container\Container类,可见该类也是个容器。是整个框架最大的容器;
该类的构造器代码如下:
public function __construct($basePath = null) { if ($basePath) { // 设置应用程序根目录 $this->setBasePath($basePath); } // 注册基础绑定服务 // 1. 设置当前类为容器实例 // 2. 设置实例别名为app $this->registerBaseBindings(); // 注册基础服务提供商 // 1. 注册事件服务提供商 // 2. 注册日志服务提供商 // 3. 注册路由服务提供商 $this->registerBaseServiceProviders(); // 注册核心容器别名 // 为一些核心类设置别名, // 存储在父类的$aliases和abstractAliases属性数组中。 // $aliases 为 别名 => 类名 键值对 // $abstractAliases 为 类名 => 别名 键值对 $this->registerCoreContainerAliases(); }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
设置接口类的实现类,并使用单例模式实例化实现类。
// 设置HTTP内核实现类 // 配置各种中间件 $app->singleton( Illuminate\Contracts\Http\Kernel::class, App\Http\Kernel::class ); // 设置Console内核实现类 $app->singleton( Illuminate\Contracts\Console\Kernel::class, App\Console\Kernel::class ); // 设置异常处理实现类 $app->singleton( Illuminate\Contracts\Debug\ExceptionHandler::class, App\Exceptions\Handler::class );1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
获得Http内核Kernel的示例
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);1
2
1
2
http内核黑箱操作,接收request参数,返回一个response。这一步完整个程序的所有操作,形成一个完成的http请求,至于该请求的具体处理,则有kernel内部调度。这里是重点所在。
Http响应,发送Http响应头以及响应内容,代码如下:
$response->send(); /** * Sends HTTP headers and content. * * Symfony\Component\HttpFoundation\Response -> send函数 * @return $this */ public function send() { $this->sendHeaders(); $this->sendContent(); if (function_exists('fastcgi_finish_request')) { fastcgi_finish_request(); } elseif ('cli' !== PHP_SAPI) { static::closeOutputBuffers(0, true); } return $this; }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
结束所有中间件以及可终止程序
$kernel->terminate($request, $response); /** * Call the terminate method on any terminable middleware. * * Illuminate\Foundation\Http\Kernel -> terminate函数 * @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Response $response * @return void */ public function terminate($request, $response) { $this->terminateMiddleware($request, $response); $this->app->terminate(); }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
执行流程
加载框架类库,创建容器,接收request请求。以管道的设计模式 执行部分中间件
路由解析调度
实例化当前控制器
执行web中间件
执行控制器中间件
执行控制器操作
返回response
接收框架
总结
以前很公共的东西都习惯放在控制器基类的构造函数中,但是在lavarvel5.3以后却不能这么做了,因为由上述执行流程可以看出,web中间件在控制器实例化之后才执行,所以在控制器构造函数执行是session还没有初始化,即在控制器构造函数中获得不了session数据。所以也就获得不了当前用户。所以导致很多操作都做不了了。但是laravel提供了可插拔形式的中间件很好的解决了这个问题。自定义中间件在web中间件之后,Action之前执行。所以很多之前放在构造函数里的操作都可以放在中间件里解决。laravel框架中使用了大量的static:: (后期静态绑定),单独看代码很难知道调用的函数时那个类的。只有在用运行的时候,才会动态计算出,调用的是那个类的函数。如下面代码:
/* * * @see Illuminate\Support\Facades * */ public static function __callStatic($method, $args) { $instance = static::getFacadeRoot(); if (!$instance) { throw new RuntimeException('A facade root has not been set.'); } return $instance->$method(...$args); }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
这段代码来自 Illuminate\Support\Facades这个类。该类是一个抽象类。我们用的非常多的一个类Auth就是集成该类。
我们都知道Auth中有很多静态函数,如:Auth::check(),Auth::user(),Auth::guest()等等,但是当我们打开Auth类的时候,发现里面并没有这些方法,而他的父类facades中也没有这些方法。只有这个__callStatic函数。从名称不难看出,这是一个静态类的魔术方法。调用所有不存在的静态方法都会调用改函数。
从该函数的实现不难看出,该函数很像是一个工厂函数,获得当前调用函数的实例化对象,然后再调用该函数。 该函数就想是单入口的web程序的入口文件,
相关文章推荐
- [置顶] Laravel 框架 容器解析具体的某一个类 的执行 流程
- Android图片加载框架最全解析(二),从源码的角度理解Glide的执行流程
- CodeIgniter框架——CI的执行流程
- ThinkPHP中的跨控制器调用与框架执行流程
- ThinkPHP2.2框架执行流程图,ThinkPHP控制器的执行流程
- 轻量级前端MVVM框架avalon - 执行流程2
- laravel框架学习(四)执行创建中间件后,提示无法找到该中间件的解决方法
- YII框架分析笔记1:YII执行流程
- 【zendframework】框架执行流程
- ThinkPHP框架开发的应用的标准执行流程
- PHP yii 框架源码阅读(二) - 整体执行流程分析
- Laravel 门面执行流程的简单分析
- ThinkPHP 3.23 框架执行流程分析
- ci框架执行流程
- Laravel框架中实现supervisor执行异步进程
- 搭建Laravel框架流程
- Laravel框架执行原生SQL语句及使用paginate分页的方法
- nginx学习笔记七(nginx HTTP框架的执行流程)
- Yii框架执行流程
- Linux spi驱动框架之执行流程-nuc970-att7022