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 类

该类的继承结构如下:

laravel5源码讲解整理_第1张图片

第三十五行代码

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

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

 

你可能感兴趣的:(laravel5源码讲解整理)