当前位置:首页 > CMS教程 > 其它CMS > 列表

Laravel框架生命周期与原理分析

发布:smiling 来源: PHP粉丝网  添加日期:2021-09-27 09:30:41 浏览: 评论:0 

本文实例讲述了Laravel框架生命周期与原理。分享给大家供大家参考,具体如下:

引言:如果你对一件工具的使用原理了如指掌,那么你在用这件工具的时候会充满信心!

正文:一旦用户(浏览器)发送了一个HTTP请求,我们的apache或者nginx一般都转到index.php,因此,之后的一系列步骤都是从index.php开始的,我们先来看一看这个文件代码。

  1. <?php 
  2. require __DIR__.'/../bootstrap/autoload.php'
  3. $app = require_once __DIR__.'/../bootstrap/app.php'
  4. /* 
  5. |-------------------------------------------------------------------------- 
  6. | Run The Application 
  7. |-------------------------------------------------------------------------- 
  8. | 
  9. | Once we have the application, we can handle the incoming request 
  10. | through the kernel, and send the associated response back to 
  11. | the client's browser allowing them to enjoy the creative 
  12. | and wonderful application we have prepared for them. 
  13. | 
  14. */ 
  15. $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); 
  16. $response = $kernel->handle( 
  17.   $request = Illuminate\Http\Request::capture() 
  18. ); 
  19. $response->send(); 
  20. $kernel->terminate($request$response); 

作者在注释里谈了kernel的作用,kernel的作用,kernel处理来访的请求,并且发送相应返回给用户浏览器。

这里又涉及到了一个app对象,所以附上app对象,所以附上app对象的源码,这份源码是\bootstrap\app.php

  1. <?php 
  2. /* 
  3. |-------------------------------------------------------------------------- 
  4. | Create The Application 
  5. |-------------------------------------------------------------------------- 
  6. | 
  7. | The first thing we will do is create a new Laravel application instance 
  8. | which serves as the "glue" for all the components of Laravel, and is 
  9. | the IoC container for the system binding all of the various parts. 
  10. | 
  11. */ 
  12. $app = new Illuminate\Foundation\Application( 
  13.   realpath(__DIR__.'/../'
  14. ); 
  15. /* 
  16. |-------------------------------------------------------------------------- 
  17. | Bind Important Interfaces 
  18. |-------------------------------------------------------------------------- 
  19. | 
  20. | Next, we need to bind some important interfaces into the container so 
  21. | we will be able to resolve them when needed. The kernels serve the 
  22. | incoming requests to this application from both the web and CLI. 
  23. | 
  24. */ 
  25. $app->singleton( 
  26.   Illuminate\Contracts\Http\Kernel::class
  27.   App\Http\Kernel::class 
  28. ); 
  29. $app->singleton( 
  30.   Illuminate\Contracts\Console\Kernel::class
  31.   App\Console\Kernel::class 
  32. ); 
  33. $app->singleton( 
  34.   Illuminate\Contracts\Debug\ExceptionHandler::class
  35.   App\Exceptions\Handler::class 
  36. ); 
  37. /* 
  38. |-------------------------------------------------------------------------- 
  39. | Return The Application 
  40. |-------------------------------------------------------------------------- 
  41. | 
  42. | This script returns the application instance. The instance is given to 
  43. | the calling script so we can separate the building of the instances 
  44. | from the actual running of the application and sending responses. 
  45. | 
  46. */ 
  47. return $app

请看app变量是Illuminate\Foundation\Application类的对象,所以调用了这个类的构造函数,具体做了什么事,我们看源码。

  1. public function __construct($basePath = null) 
  2.   if ($basePath) { 
  3.     $this->setBasePath($basePath); 
  4.   } 
  5.   $this->registerBaseBindings(); 
  6.   $this->registerBaseServiceProviders(); 
  7.   $this->registerCoreContainerAliases(); 

构造器做了3件事,前两件事很好理解,创建Container,注册了ServiceProvider,看代码

  1. /** 
  2.  * Register the basic bindings into the container. 
  3.  * 
  4.  * @return void 
  5.  */ 
  6. protected function registerBaseBindings() 
  7.   static::setInstance($this); 
  8.   $this->instance('app'$this); 
  9.   $this->instance(Container::class$this); 
  10. /** 
  11.  * Register all of the base service providers. 
  12.  * 
  13.  * @return void 
  14.  */ 
  15. protected function registerBaseServiceProviders() 
  16.   $this->register(new EventServiceProvider($this)); 
  17.   $this->register(new LogServiceProvider($this)); 
  18.   $this->register(new RoutingServiceProvider($this)); 

最后一件事,是做了个很大的数组,定义了大量的别名,侧面体现程序员是聪明的懒人。

  1. /** 
  2.  * Register the core class aliases in the container. 
  3.  * 
  4.  * @return void 
  5.  */ 
  6. public function registerCoreContainerAliases() 
  7.   $aliases = [ 
  8.     'app'         => [\Illuminate\Foundation\Application::class, \Illuminate\Contracts\Container\Container::class, \Illuminate\Contracts\Foundation\Application::class], 
  9.     'auth'         => [\Illuminate\Auth\AuthManager::class, \Illuminate\Contracts\Auth\Factory::class], 
  10.     'auth.driver'     => [\Illuminate\Contracts\Auth\Guard::class], 
  11.     'blade.compiler'    => [\Illuminate\View\Compilers\BladeCompiler::class], 
  12.     'cache'        => [\Illuminate\Cache\CacheManager::class, \Illuminate\Contracts\Cache\Factory::class], 
  13.     'cache.store'     => [\Illuminate\Cache\Repository::class, \Illuminate\Contracts\Cache\Repository::class], 
  14.     'config'        => [\Illuminate\Config\Repository::class, \Illuminate\Contracts\Config\Repository::class], 
  15.     'cookie'        => [\Illuminate\Cookie\CookieJar::class, \Illuminate\Contracts\Cookie\Factory::class, \Illuminate\Contracts\Cookie\QueueingFactory::class], 
  16.     'encrypter'      => [\Illuminate\Encryption\Encrypter::class, \Illuminate\Contracts\Encryption\Encrypter::class], 
  17.     'db'          => [\Illuminate\Database\DatabaseManager::class], 
  18.     'db.connection'    => [\Illuminate\Database\Connection::class, \Illuminate\Database\ConnectionInterface::class], 
  19.     'events'        => [\Illuminate\Events\Dispatcher::class, \Illuminate\Contracts\Events\Dispatcher::class], 
  20.     'files'        => [\Illuminate\Filesystem\Filesystem::class], 
  21.     'filesystem'      => [\Illuminate\Filesystem\FilesystemManager::class, \Illuminate\Contracts\Filesystem\Factory::class], 
  22.     'filesystem.disk'   => [\Illuminate\Contracts\Filesystem\Filesystem::class], 
  23.     'filesystem.cloud'   => [\Illuminate\Contracts\Filesystem\Cloud::class], 
  24.     'hash'         => [\Illuminate\Contracts\Hashing\Hasher::class], 
  25.     'translator'      => [\Illuminate\Translation\Translator::class, \Illuminate\Contracts\Translation\Translator::class], 
  26.     'log'         => [\Illuminate\Log\Writer::class, \Illuminate\Contracts\Logging\Log::class, \Psr\Log\LoggerInterface::class], 
  27.     'mailer'        => [\Illuminate\Mail\Mailer::class, \Illuminate\Contracts\Mail\Mailer::class, \Illuminate\Contracts\Mail\MailQueue::class], 
  28.     'auth.password'    => [\Illuminate\Auth\Passwords\PasswordBrokerManager::class, \Illuminate\Contracts\Auth\PasswordBrokerFactory::class], 
  29.     'auth.password.broker' => [\Illuminate\Auth\Passwords\PasswordBroker::class, \Illuminate\Contracts\Auth\PasswordBroker::class], 
  30.     'queue'        => [\Illuminate\Queue\QueueManager::class, \Illuminate\Contracts\Queue\Factory::class, \Illuminate\Contracts\Queue\Monitor::class], 
  31.     'queue.connection'   => [\Illuminate\Contracts\Queue\Queue::class], 
  32.     'queue.failer'     => [\Illuminate\Queue\Failed\FailedJobProviderInterface::class], 
  33.     'redirect'       => [\Illuminate\Routing\Redirector::class], 
  34.     'redis'        => [\Illuminate\Redis\RedisManager::class, \Illuminate\Contracts\Redis\Factory::class], 
  35.     'request'       => [\Illuminate\Http\Request::class, \Symfony\Component\HttpFoundation\Request::class], 
  36.     'router'        => [\Illuminate\Routing\Router::class, \Illuminate\Contracts\Routing\Registrar::class, \Illuminate\Contracts\Routing\BindingRegistrar::class], 
  37.     'session'       => [\Illuminate\Session\SessionManager::class], 
  38.     'session.store'    => [\Illuminate\Session\Store::class, \Illuminate\Contracts\Session\Session::class], 
  39.     'url'         => [\Illuminate\Routing\UrlGenerator::class, \Illuminate\Contracts\Routing\UrlGenerator::class], 
  40.     'validator'      => [\Illuminate\Validation\Factory::class, \Illuminate\Contracts\Validation\Factory::class], 
  41.     'view'         => [\Illuminate\View\Factory::class, \Illuminate\Contracts\View\Factory::class], 
  42.   ]; 
  43.   foreach ($aliases as $key => $aliases) { 
  44.     foreach ($aliases as $alias) { 
  45.       $this->alias($key$alias); 
  46.     } 
  47.   } 

这里出现了一个instance函数,其实这并不是Application类的函数,而是Application类的父类Container类的函数。

  1. /** 
  2.  * Register an existing instance as shared in the container. 
  3.  * 
  4.  * @param string $abstract 
  5.  * @param mixed  $instance 
  6.  * @return void 
  7.  */ 
  8. public function instance($abstract$instance
  9.   $this->removeAbstractAlias($abstract); 
  10.   unset($this->aliases[$abstract]); 
  11.   // We'll check to determine if this type has been bound before, and if it has 
  12.   // we will fire the rebound callbacks registered with the container and it 
  13.   // can be updated with consuming classes that have gotten resolved here. 
  14.   $this->instances[$abstract] = $instance
  15.   if ($this->bound($abstract)) { 
  16.     $this->rebound($abstract); 
  17.   } 

Application是Container的子类,所以$app不仅是Application类的对象,还是Container的对象,所以,新出现的singleton函数我们就可以到Container类的源代码文件里查。bind函数和singleton的区别见这篇博文。

singleton这个函数,前一个参数是实际类名,后一个参数是类的“别名”。

$app对象声明了3个单例模型对象,分别是HttpKernel,ConsoleKernel,ExceptionHandler。请注意,这里并没有创建对象,只是声明,也只是起了一个“别名”。

大家有没有发现,index.php中也有一个$kernel变量,但是只保存了make出来的HttpKernel变量,因此本文不再讨论,ConsoleKernel,ExceptionHandler。。。

继续在文件夹下找到App\Http\Kernel.php,既然我们把实际的HttpKernel做的事情都写在这个php文件里,就从这份代码里看看究竟做了哪些事?

  1. <?php 
  2. namespace App\Http; 
  3. use Illuminate\Foundation\Http\Kernel as HttpKernel; 
  4. class Kernel extends HttpKernel 
  5.   /** 
  6.    * The application's global HTTP middleware stack. 
  7.    * 
  8.    * These middleware are run during every request to your application. 
  9.    * 
  10.    * @var array 
  11.    */ 
  12.   protected $middleware = [ 
  13.     \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class
  14.     //\App\Http\Middleware\MyMiddleware::class, 
  15.   ]; 
  16.   /** 
  17.    * The application's route middleware groups. 
  18.    * 
  19.    * @var array 
  20.    */ 
  21.   protected $middlewareGroups = [ 
  22.     'web' => [ 
  23.       \App\Http\Middleware\EncryptCookies::class
  24.       \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class
  25.       \Illuminate\Session\Middleware\StartSession::class
  26.       \Illuminate\View\Middleware\ShareErrorsFromSession::class
  27.       \App\Http\Middleware\VerifyCsrfToken::class
  28.     ], 
  29.     'api' => [ 
  30.       'throttle:60,1'
  31.     ], 
  32.   ]; 
  33.   /** 
  34.    * The application's route middleware. 
  35.    * 
  36.    * These middleware may be assigned to groups or used individually. 
  37.    * 
  38.    * @var array 
  39.    */ 
  40.   protected $routeMiddleware = [ 
  41.     'auth' => \App\Http\Middleware\Authenticate::class
  42.     'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class
  43.     'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class
  44.     'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class
  45.   'mymiddleware'=>\App\Http\Middleware\MyMiddleware::class
  46.   ]; 

一目了然,HttpKernel里定义了中间件数组。

该做的做完了,就开始了请求到响应的过程,见index.php

  1. $response = $kernel->handle( 
  2.   $request = Illuminate\Http\Request::capture() 
  3. ); 
  4. $response->send(); 

最后在中止,释放所有资源。

  1. /** 
  2. * Call the terminate method on any terminable middleware. 
  3. * 
  4. * @param \Illuminate\Http\Request $request 
  5. * @param \Illuminate\Http\Response $response 
  6. * @return void 
  7. */ 
  8. public function terminate($request$response
  9.     $this->terminateMiddleware($request$response); 
  10.     $this->app->terminate(); 

总结一下,简单归纳整个过程就是:

1.index.php加载\bootstrap\app.php,在Application类的构造函数中创建Container,注册了ServiceProvider,定义了别名数组,然后用app变量保存构造函数构造出来的对象。

2.使用app这个对象,创建1个单例模式的对象HttpKernel,在创建HttpKernel时调用了构造函数,完成了中间件的声明。

3.以上这些工作都是在请求来访之前完成的,接下来开始等待请求,然后就是:接受到请求-->处理请求-->发送响应-->中止app变量

Tags: Laravel生命周期

分享到: