程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> laravel5源碼講解整理,laravel5源碼講解

laravel5源碼講解整理,laravel5源碼講解

編輯:關於PHP編程

laravel5源碼講解整理,laravel5源碼講解


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

目錄

  • 入口文件 index.php
    • Illuminate\Foundation\Application 類
    • 注入所有基礎 Service Provider

 

入口文件 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 <[email protected]>
 */

/*
|--------------------------------------------------------------------------
| 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(Illuminate\Contracts\Http\Kernel::class);

$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);

$response->send();

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

第二十一行代碼

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

為Laravel應用引入了由Composer提供的類加載器,這樣Laravel應用便無需再手動加載任 何的類。其加載原理不是此次探究的目標,所以僅僅這樣使用就好了。接下的代碼,便是重 點。

 

Illuminate\Foundation\Application 類

該類的繼承結構如下:

類繼承結構

第三十五行代碼

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 Illuminate\Foundation\Application(
    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(
    Illuminate\Contracts\Http\Kernel::class,
    App\Http\Kernel::class
);

$app->singleton(
    Illuminate\Contracts\Console\Kernel::class,
    App\Console\Kernel::class
);

$app->singleton(
    Illuminate\Contracts\Debug\ExceptionHandler::class,
    App\Exceptions\Handler::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是一個 Illuminate\Foundation\Application 對象,那麼在創 建這個對象的時候又發生了什麼呢?

從它的構造方法看起:

Illuminate\Foundation\Application 構造方法

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方法。

Illuminate\Foundation\Application#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('Illuminate\Container\Container', $this);
}

這段代碼,是將實例對象注入到容器中。那麼,這個容器是什麼呢?答案還是要從這段調用 中去尋找。

static::setInstance($this) 所做的就是將 $this 賦值給自身的 instance 靜態變 量。重點看 $this->instance('app', $this)

instance 函數的作用是綁定一個已有對象到容器中,這個對象在容器中共享並且可以通 過鍵獲取。

Illuminate\Container\Container#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()

Illuminate\Foundation\Application#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  \Illuminate\Support\ServiceProvider|string  $provider
  * @param  array  $options
  * @param  bool   $force
  * @return \Illuminate\Support\ServiceProvider
  */
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分別是

  • Illuminate\Events\EventServiceProvider
  • Illuminate\Routing\RoutingServiceProvider

這些ServiceProvider是 Illuminate\Support\ServiceProvider 的子類,它接受一個 Application 對象作為構造函數參數,存儲在實例變量 $app 中。

 

注入所有基礎 Service Provider

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

Illuminate\Events\EventServiceProvider#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('Illuminate\Contracts\Queue\Factory');
        });
    });
}

上面方法體將一個 Illuminate\Events\Dispatcher 對象以鍵 events 綁定到了容器 中,它負責實現事件的調度。

再看看 Illuminate\Routing\RoutingServiceProvider:

Illuminate\Routing\RoutingServiceProvider#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 被注冊,它是 Illuminate\Routing\Router 對象。

 

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

其他好文

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

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

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved