• laravel5源码讲解整理


    来源:http://yuez.me/laravel-yuan-ma-jie-du/?utm_source=tuicool&utm_medium=referral

    目录

    入口文件 index.php

    一个基于Laravel的应用,当WEB服务器接受到来自外部的请求后,会将这个这个请求解析到 应用根目录的 public/index.php 中。

    Laravel源码解读-index.php (laravel_index.php)download

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    
    <?php
    /**
     * Laravel - A PHP Framework For Web Artisans
     *
     * @package  Laravel
     * @author   Taylor Otwell <taylorotwell@gmail.com>
     */
    
    /*
    |--------------------------------------------------------------------------
    | Register The Auto Loader
    |--------------------------------------------------------------------------
    |
    | Composer provides a convenient, automatically generated class loader for
    | our application. We just need to utilize it! We'll simply require it
    | into the script here so that we don't have to worry about manual
    | loading any of our classes later on. It feels nice to relax.
    |
    */
    
    require __DIR__.'/../bootstrap/autoload.php';
    
    /*
    |--------------------------------------------------------------------------
    | Turn On The Lights
    |--------------------------------------------------------------------------
    |
    | We need to illuminate PHP development, so let us turn on the lights.
    | This bootstraps the framework and gets it ready for use, then it
    | will load up this application so that we can run it and send
    | the responses back to the browser and delight our users.
    |
    */
    
    $app = require_once __DIR__.'/../bootstrap/app.php';
    
    /*
    |--------------------------------------------------------------------------
    | Run The Application
    |--------------------------------------------------------------------------
    |
    | Once we have the application, we can handle the incoming request
    | through the kernel, and send the associated response back to
    | the client's browser allowing them to enjoy the creative
    | and wonderful application we have prepared for them.
    |
    */
    
    $kernel = $app->make(IlluminateContractsHttpKernel::class);
    
    $response = $kernel->handle(
        $request = IlluminateHttpRequest::capture()
    );
    
    $response->send();
    
    $kernel->terminate($request, $response);
    

    第二十一行代码

    1
    
    require __DIR__.'/../bootstrap/autoload.php';
    

    为Laravel应用引入了由Composer提供的类加载器,这样Laravel应用便无需再手动加载任 何的类。其加载原理不是此次探究的目标,所以仅仅这样使用就好了。接下的代码,便是重 点。

    IlluminateFoundationApplication 类

    该类的继承结构如下:

    类继承结构

    第三十五行代码

    1
    
    $app = require_once __DIR__.'/../bootstrap/app.php';
    

    它将我的视线引入到了另外一个文件中,去看看到底发生了什么吧。

    Laravel源码解读-app.php (laravel_app.php)download

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    
    <?php
    
    /*
    |--------------------------------------------------------------------------
    | Create The Application
    |--------------------------------------------------------------------------
    |
    | The first thing we will do is create a new Laravel application instance
    | which serves as the "glue" for all the components of Laravel, and is
    | the IoC container for the system binding all of the various parts.
    |
    */
    
    $app = new IlluminateFoundationApplication(
        realpath(__DIR__.'/../')
    );
    
    /*
    |--------------------------------------------------------------------------
    | Bind Important Interfaces
    |--------------------------------------------------------------------------
    |
    | Next, we need to bind some important interfaces into the container so
    | we will be able to resolve them when needed. The kernels serve the
    | incoming requests to this application from both the web and CLI.
    |
    */
    
    $app->singleton(
        IlluminateContractsHttpKernel::class,
        AppHttpKernel::class
    );
    
    $app->singleton(
        IlluminateContractsConsoleKernel::class,
        AppConsoleKernel::class
    );
    
    $app->singleton(
        IlluminateContractsDebugExceptionHandler::class,
        AppExceptionsHandler::class
    );
    
    /*
    |--------------------------------------------------------------------------
    | Return The Application
    |--------------------------------------------------------------------------
    |
    | This script returns the application instance. The instance is given to
    | the calling script so we can separate the building of the instances
    | from the actual running of the application and sending responses.
    |
    */
    
    return $app;
    

    看第十四行,原来$app是一个 IlluminateFoundationApplication 对象,那么在创 建这个对象的时候又发生了什么呢?

    从它的构造方法看起:

    IlluminateFoundationApplication 构造方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    /**
     * Create a new Illuminate application instance.
     *
     * @param  string|null  $basePath
     * @return void
     */
    public function __construct($basePath = null)
    {
        $this->registerBaseBindings();
    
        $this->registerBaseServiceProviders();
    
        $this->registerCoreContainerAliases();
    
        if ($basePath) {
            $this->setBasePath($basePath);
        }
    }
    

    顺着函数调用,往下看。在这个构造函数中,首先调用了registerBaseBindings方法。

    IlluminateFoundationApplication#registerBaseBindings

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    /**
      * Register the basic bindings into the container.
      *
      * @return void
      */
    protected function registerBaseBindings()
    {
        static::setInstance($this);
    
        $this->instance('app', $this);
    
        $this->instance('IlluminateContainerContainer', $this);
    }
    

    这段代码,是将实例对象注入到容器中。那么,这个容器是什么呢?答案还是要从这段调用 中去寻找。

    static::setInstance($this) 所做的就是将 $this 赋值给自身的 instance 静态变 量。重点看 $this->instance('app', $this)

    instance 函数的作用是绑定一个已有对象到容器中,这个对象在容器中共享并且可以通 过键获取。

    IlluminateContainerContainer#instance

    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
    
    /**
      * Register an existing instance as shared in the container.
      *
      * @param  string  $abstract
      * @param  mixed   $instance
      * @return void
      */
    public function instance($abstract, $instance)
    {
        if (is_array($abstract)) {
            // $abstract 是这样的一个数组 ['actual key' => 'alias']
            list($abstract, $alias) = $this->extractAlias($abstract);
    
            // 实际上的行为是 $this->aliases[$alias] = $abstract;
            $this->alias($abstract, $alias);
        }
    
        unset($this->aliases[$abstract]);
    
        // 检查是否有这个键是否已经注册到容器中
        // $bound 是一个boolean值
        $bound = $this->bound($abstract);
    
        $this->instances[$abstract] = $instance;
    
        if ($bound) {
            $this->rebound($abstract);
        }
    }
    

    视线重新回到Application类中,接下来调用了这个方法 $this->registerBaseServiceProviders()

    IlluminateFoundationApplication#registerBaseServiceProviders

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    
    /**
      * Register all of the base service providers.
      *
      * @return void
      */
    protected function registerBaseServiceProviders()
    {
        $this->register(new EventServiceProvider($this));
    
        $this->register(new RoutingServiceProvider($this));
    }
    
    /**
      * Register a service provider with the application.
      *
      * @param  IlluminateSupportServiceProvider|string  $provider
      * @param  array  $options
      * @param  bool   $force
      * @return IlluminateSupportServiceProvider
      */
    public function register($provider, $options = [], $force = false)
    {
        if ($registered = $this->getProvider($provider) && !$force) {
            return $registered;
        }
    
        // If the given "provider" is a string, we will resolve it, passing in the
        // application instance automatically for the developer. This is simply
        // a more convenient way of specifying your service provider classes.
        if (is_string($provider)) {
            $provider = $this->resolveProviderClass($provider);
        }
    
        $provider->register();
    
        // Once we have registered the service we will iterate through the options
        // and set each of them on the application so they will be available on
        // the actual loading of the service objects and for developer usage.
        foreach ($options as $key => $value) {
            $this[$key] = $value;
        }
    
        $this->markAsRegistered($provider);
    
        // If the application has already booted, we will call this boot method on
        // the provider class so it has an opportunity to do its boot logic and
        // will be ready for any usage by the developer's application logics.
        if ($this->booted) {
            $this->bootProvider($provider);
        }
    
        return $provider;
    }
    

    其中,EventServiceProvider和RoutingServiceProvider分别是

    • IlluminateEventsEventServiceProvider
    • IlluminateRoutingRoutingServiceProvider

    这些ServiceProvider是 IlluminateSupportServiceProvider 的子类,它接受一个 Application 对象作为构造函数参数,存储在实例变量 $app 中。

    注入所有基础 Service Provider

    在 register 方法中,每个ServiceProvider被调用了自身的 register 方法。首先看 看 EventServiceProvider 中的吧。

    IlluminateEventsEventServiceProvider#register

    1
    2
    3
    4
    5
    6
    7
    8
    
    public function register()
    {
        $this->app->singleton('events', function ($app) {
            return (new Dispatcher($app))->setQueueResolver(function () use ($app) {
                return $app->make('IlluminateContractsQueueFactory');
            });
        });
    }
    

    上面方法体将一个 IlluminateEventsDispatcher 对象以键 events 绑定到了容器 中,它负责实现事件的调度。

    再看看 IlluminateRoutingRoutingServiceProvider:

    IlluminateRoutingRoutingServiceProvider#register

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    public function register()
    {
        $this->registerRouter();
    
        $this->registerUrlGenerator();
    
        $this->registerRedirector();
    
        $this->registerPsrRequest();
    
        $this->registerPsrResponse();
    
        $this->registerResponseFactory();
    }
    

    首页是在Laravel中接触的最多的 route 被注册,它是 IlluminateRoutingRouter 对象。

    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    其他好文

    http://www.cnblogs.com/wish123/p/4756669.html

    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

  • 相关阅读:
    fluentValidation集成到autofac
    javascript中的this
    Android环境配置Sencha Touch
    PHP上传图片如何防止图片木马?
    mysql 修改字段长度
    mysql 截取字符
    php 获取文件后缀名
    mysql 导入导出数据库、数据表
    Nginx下修改php.ini后重新加载配置文件命令
    ubuntu 12.04 LTS(64位)安装apache2
  • 原文地址:https://www.cnblogs.com/dytl/p/4967753.html
Copyright © 2020-2023  润新知