文档章节

分析,理解,优化Laravel

ChefXu
 ChefXu
发布于 2016/04/19 16:54
字数 1083
阅读 149
收藏 1

分析,理解,优化Laravel

#前言 使用Laravel接近两年了, 从4.2到现在的5.2。大多数情况下,Laravel都能很好的支撑我们的系统。不管你是否使用或打算使用, 了解Laravel的设计对于提高程序水平也很有帮助。本文是我的一个学习laravel的过程, 也是我实现高性能server stone下一个目标的过程。限于本人水平有限,错误在所难免,希望大家不吝指正。

注:因为是边写边改, 所以内容目录随时会有调整。

#一个HTTP请求的执行流程

  1. 创建app, app本质上是一个ioc容器(Illuminate\Container\Container),这个概念对于laravel很重要,laravel的核心组件都会注册到这个容器里面。

    $app = new Illuminate\Foundation\Application(
        realpath(__DIR__.'/../')
    );
    
    • 初始化全局ioc容器app, 并把自己本身注册进去
    • 注册基本的Service Provider: EventServiceProvider, RoutingServiceProvider
    • 注册核心的class别名,参看:registerCoreContainerAliases
  2. 核心接口绑定, 如果需替换自己实现的Kernel, 可以修改这里。

    // 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
    );
    
  3. 创建Kernel,注意这里是基于接口来创建, 最终创建什么实例, 依赖于前面的接口绑定。

    $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
    
    • 这个代码最终实例化的是App\Http\Kernel,App\Http\Kernel继承自Illuminate\Foundation\Http\Kernel。

    • 接口绑定是laravel框架设计精华所在,laravel框架的核心组件全部都实现了接口,在laravel里统一放在Contracts下。这给予了开发者极大的自由,可以在程序中通过修改接口绑定来改变组件的实现。

      chunfang@office:~/base.account$ ls vendor/laravel/framework/src/Illuminate/Contracts/
      Auth          Bus    composer.json  Console    Cookie    Debug       Events      
      Foundation  Http     Mail        Pipeline  Redis    Support     View
      Broadcasting  Cache  Config         Container  Database  Encryption  Filesystem  
      Hashing     Logging  Pagination  Queue     Routing  Validation
      
  4. 基于全局变量创建request对象, 交由Kernel处理, 这是请求处理的核心所在。

    • 基于全局变量创建请求

      $request = Illuminate\Http\Request::capture()
      
    • Kerner处理request

      $response = $kernel->handle($request);
      

      请求方法关键细节:

      /**
       * Handle an incoming HTTP request.
       *
       * @param  \Illuminate\Http\Request  $request
       * @return \Illuminate\Http\Response
       */
      public function handle($request)
      {
          try {
              // 允许使用_method来模拟PUT,DELETE等
              $request->enableHttpMethodParameterOverride();
      
              // 处理请求返回响应
              $response = $this->sendRequestThroughRouter($request);
          } catch (Exception $e) {
              $this->reportException($e);
      
              $response = $this->renderException($request, $e);
          } catch (Throwable $e) {
              $this->reportException($e = new FatalThrowableError($e));
      
              $response = $this->renderException($request, $e);
          }
      
          // 发射事件
          $this->app['events']->fire('kernel.handled', [$request, $response]);
      
          return $response;
      }
      
      

      处理请求返回响应关键细节:

      /**
       * Send the given request through the middleware / router.
       *
       * @param  \Illuminate\Http\Request  $request
       * @return \Illuminate\Http\Response
       */
      protected function sendRequestThroughRouter($request)
      {
          $this->app->instance('request', $request);
      
          Facade::clearResolvedInstance('request');
      
          // 初始化请求资源
          $this->bootstrap();
      
          // 流水线处理
          return (new Pipeline($this->app))
                      ->send($request)
                      ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
                      ->then($this->dispatchToRouter());
      }
      

      初始化资源关键细节:

      protected $bootstrappers = [
          'Illuminate\Foundation\Bootstrap\DetectEnvironment',
          'Illuminate\Foundation\Bootstrap\LoadConfiguration',
          'Illuminate\Foundation\Bootstrap\ConfigureLogging',
          'Illuminate\Foundation\Bootstrap\HandleExceptions',
          'Illuminate\Foundation\Bootstrap\RegisterFacades',
          'Illuminate\Foundation\Bootstrap\RegisterProviders',
          'Illuminate\Foundation\Bootstrap\BootProviders',
      ];
      

      流水线实现细节: 理解Laravel中的pipeline

      路由处理关键细节:

      /**
       * Dispatch the request to the application.
       *
       * @param  \Illuminate\Http\Request  $request
       * @return \Illuminate\Http\Response
       */
      public function dispatch(Request $request)
      {
          $this->currentRequest = $request;
      
          $response = $this->dispatchToRoute($request);
      
          return $this->prepareResponse($request, $response);
      }
      
      /**
       * Dispatch the request to a route and return the response.
       *
       * @param  \Illuminate\Http\Request  $request
       * @return mixed
       */
      public function dispatchToRoute(Request $request)
      {
          // First we will find a route that matches this request. We will also set the
          // route resolver on the request so middlewares assigned to the route will
          // receive access to this route instance for checking of the parameters.
          $route = $this->findRoute($request);
      
          $request->setRouteResolver(function () use ($route) {
              return $route;
          });
      
          $this->events->fire(new Events\RouteMatched($route, $request));
      
          $response = $this->runRouteWithinStack($route, $request);
      
          return $this->prepareResponse($request, $response);
      }
      

      路由执行实际动作关键细节:

      /**
       * Run the route action and return the response.
       *
       * @param  \Illuminate\Http\Request  $request
       * @return mixed
       */
      public function run(Request $request)
      {
          $this->container = $this->container ?: new Container;
      
          try {
              if (! is_string($this->action['uses'])) {
                  return $this->runCallable($request);
              }
      
              return $this->runController($request);
          } catch (HttpResponseException $e) {
              return $e->getResponse();
          }
      }
      
  5. 输出到客户端

    $response->send();
    
  6. 依次调用结束动作

    $kernel->terminate($request, $response);
    

IOC容器的实现

编写中

实现自己的路由替代Laravel路由

编写中

浅析资源初始化

编写中

Laravel Pipeline的实现

编写中

基于Stone实现高性能Kernel

编写中

© 著作权归作者所有

ChefXu
粉丝 12
博文 6
码字总数 11518
作品 0
海淀
程序员
私信 提问
php&go&python&node

2016 第二届 PHP 全球开发者大会回顾(文末附演讲嘉宾所有资料下载) 继前年的 “PHP7 初探”、去年的“高性能的 PHP ” 主题后,2017 第三届 PHP 全球开发者大会的活动主题是“高可用的 PH...

掘金官方
2017/12/20
0
0
Laravel源码分析——一次Http请求到响应

1前言 在FastCGI协议下工作的php-fpm, 使用持续的进程来处理一连串的请求, 具体到某个请求的解析流程的时候, 如果不考虑扩展的方式, 基本上都是顺序的解析处理. 所以就算复杂如Laravel框架,...

hisense20112784
2017/08/22
0
0
Laravel5.4实战快速开发自媒体网站教程 Laravel实战教程

第1章 课程介绍 介绍课程的大体脉络和课程安排 第2章 Laravel 5.4介绍 本节课会带领大家介绍laravel的各个版本历史以及讨论php框架的未来发展趋势。把laravel周边的生态环境一一展示。 第3章...

15543595340
2018/05/19
0
0
Laravel 5.1 源码阅读

安装,和创建项目,都是通过Composer,简单,略过。 Entry && Kernel 网站入口文件,${Laravel-project}/public/index.PHP: 生成Request,处理Request(),生成Response,发送Resonse。常规...

botkenni
2016/10/09
52
0
如何理解 Laravel 的 Ioc 容器

学习laravel快小一年了,到现在才去研究laravel 的核心 '容器 IOC' 这些概念. 写项目的时候有大概看看关于IOC 文章, 但是没有深入理解,只是有个概念,赶着写代码, 虽然代码也写的很菜 · ...

撸啊撸
2019/09/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

如何查看Android的系统版本?

有谁知道我怎么能检查系统版本(例如1.0 , 2.2 ,等)编程? #1楼 我无法对答案发表评论,但是Kaushik的答案存在一个严重错误:SDK_INT与系统版本不同,但实际上是指API级别。 if(Build.VER...

技术盛宴
46分钟前
35
0
引入AI变量,精准农业正在加速豹变?

  不久前,“江苏省脱贫率达 99.99%,尚未脱贫人数仅剩 6 户、17 人”这样一则新闻刷屏。“把这 17 个人迁出,江苏就全省脱贫”、“最后这 6 户人家拖了后腿”,在网民们的调侃和质疑声背后...

水果黄瓜
49分钟前
41
0
Elasticsearch系列---结构化搜索

概要 结构化搜索针对日期、时间、数字等结构化数据的搜索,它们有自己的格式,我们可以对它们进行范围,比较大小等逻辑操作,这些逻辑操作得到的结果非黑即白,要么符合条件在结果集里,要么...

清茶豆奶
今天
69
0
每天AC系列(一):三数之和

1 题目 LeetCode第15题,难度中等,题目描述: 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。 注意:答...

Blueeeeeee
今天
120
0
OSChina 周四乱弹 —— 水果你们都没吃全

Osc乱弹歌单(2020)请戳(这里) 【今日歌曲】 @ 莱布妮子:分享五月天的单曲《温柔》@小小编辑 @cIouddyy @clouddyy 《温柔》- 五月天 手机党少年们想听歌,请使劲儿戳(这里) @FalconChe...

小小编辑
今天
1.9K
11

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部