Laravel框架源码解析之入口文件原理分析


Posted in PHP onMay 14, 2020

本文实例讲述了Laravel框架源码解析之入口文件原理。分享给大家供大家参考,具体如下:

前言

提升能力的方法并非使用更多工具,而是解刨自己所使用的工具。今天我们从Laravel启动的第一步开始讲起。

入口文件

laravel是单入口框架,所有请求必将经过index.php

define('LARAVEL_START', microtime(true)); // 获取启动时间

使用composer是现代PHP的标志

require __DIR__.'/../vendor/autoload.php'; // 加载composer -> autoload.php

加载启动文件

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

获取$app是laravel启动的关键,也可以说$app是用于启动laravel内核的钥匙?。随后就是加载内核,载入服务提供者、门面所映射的实体类,中间件,最后到接收http请求并返回结果。

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); // 加载核心类

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

$response->send();

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

看似短短的4行代码,这则是laravel的优雅之处。我们开始深层次解刨。

bootstrap\app.php

这个启动文件也可以看作是一个服务提供者,不过他并没有boot,register方法。因为入口文件直接加载他,所有这些没必要的方法就不存在了。

作为启动文件,首页则是加载框架所有必须的要要件,例如

  • registerBaseBindings
  • registerBaseServiceProviders
  • registerCoreContainerAliases,

这其中包括了很多基础性的方法和类,例如

  • db [\Illuminate\Database\DatabaseManager::class]
  • auth [\Illuminate\Auth\AuthManager::class, \Illuminate\Contracts\Auth\Factory::class]
  • log [\Illuminate\Log\LogManager::class, \Psr\Log\LoggerInterface::class]
  • queue [\Illuminate\Queue\QueueManager::class, \Illuminate\Contracts\Queue\Factory::class, \Illuminate\Contracts\Queue\Monitor::class]
  • redis [\Illuminate\Redis\RedisManager::class, \Illuminate\Contracts\Redis\Factory::class]
  • 等等 ...

而$app这个在服务提供者的核心变量则就是Application实例化所得,而你在服务提供者内使用的make,bind,singleton来自他的父类Container,都说容器是laravel的核心概念。这块的概念后续我们会详细的讲解。

$app = new Illuminate\Foundation\Application(
 realpath(__DIR__.'/../')
);

上面我们已经获得$app的实例化了,现在通过$app来注册核心类、异常类,并将$app返回给index.php

$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
);

App\Http\Kernel

核心类了所有的

  • 系统中间件
  • 群组中间件
  • 路由中间件

当然你需要使用中间件也是在这个类中加载,是经常被使用的一个文件。

protected $middleware = [
   \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
   \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
   \App\Http\Middleware\TrimStrings::class,
   \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
   \App\Http\Middleware\TrustProxies::class,
  ];
  
  /**
   * The application's route middleware groups.
   *
   * @var array
   */
  protected $middlewareGroups = [
   'web' => [
    \App\Http\Middleware\EncryptCookies::class,
    \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
    \Illuminate\Session\Middleware\StartSession::class,
    // \Illuminate\Session\Middleware\AuthenticateSession::class,
    \Illuminate\View\Middleware\ShareErrorsFromSession::class,
    \App\Http\Middleware\VerifyCsrfToken::class,
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
   ],
   
   'api' => [
    'throttle:60,1',
    'bindings',
   ],
  ];

这个核心类继承自他的父类Illuminate\Foundation\Http\Kernel::class,核心类做了很多事情,它会将所有的中间件全部存储到一个指定的数组,方便内核调用及其他类调用。

namespace App\Http;
 
use App\Api\Middleware\VerifyApiToken;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
 
class Kernel extends HttpKernel

回到起点

Laravel的启动经历了很繁琐的一个过程。这也是Laravel优雅的关键点。

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

$response->send();

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

将请求传入则完成了整个laravel的启动,至于结果的返回则有开发者自行通过控制器或其他可访问类返回。

希望本文所述对大家基于Laravel框架的PHP程序设计有所帮助。

PHP 相关文章推荐
ip签名探针
Oct 09 PHP
php异常:Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE  eval()'d code error
May 19 PHP
php设计模式小结
Feb 15 PHP
PHP字符串的编码问题的详细介绍
Apr 27 PHP
测试PHP连接MYSQL成功与否的代码
Aug 16 PHP
PHP CURL获取cookies模拟登录的方法
Nov 04 PHP
php生成QRcode实例
Sep 22 PHP
PHP+jQuery 注册模块的改进(一):验证码存入SESSION
Oct 14 PHP
php画图实例
Nov 05 PHP
关于PHP中Session文件过多的问题及session文件保存位置
Mar 17 PHP
thinkPHP5.0框架模块设计详解
Mar 18 PHP
thinkPHP5.0框架URL访问方法详解
Mar 18 PHP
Laravel框架源码解析之反射的使用详解
May 14 #PHP
PHP 数组操作详解【遍历、指针、函数等】
May 13 #PHP
ThinkPHP5 框架引入 Go AOP,PHP AOP编程项目详解
May 12 #PHP
php中用unset销毁变量并释放内存
May 10 #PHP
php屏蔽错误及提示的方法
May 10 #PHP
php判断数组是否为空的实例方法
May 10 #PHP
通过PHP实现获取访问用户IP
May 09 #PHP
You might like
PHP Google的translate API代码
2008/12/10 PHP
iis下php mail函数的sendmail配置方法(官方推荐)
2012/04/25 PHP
php将session放入memcached的设置方法
2014/02/14 PHP
thinkPHP线上自动加载异常与修复方法实例分析
2016/12/01 PHP
php 反斜杠处理函数addslashes()和stripslashes()实例详解
2016/12/25 PHP
php传值方式和ajax的验证功能
2017/03/27 PHP
JS location几个方法小姐
2008/07/09 Javascript
关于javascript document.createDocumentFragment()
2009/04/04 Javascript
Javascript 中介者模式实例
2009/12/16 Javascript
两个比较有用的Javascript工具函数代码
2010/02/17 Javascript
js简单判断移动端系统的方法
2016/02/25 Javascript
利用Angularjs和bootstrap实现购物车功能
2016/08/31 Javascript
JS数组返回去重后数据的方法解析
2017/01/03 Javascript
node.js入门学习之url模块
2017/02/25 Javascript
微信小程序授权登录解决方案的代码实例(含未通过授权解决方案)
2019/05/10 Javascript
深入浅析ng-bootstrap 组件集中 tabset 组件的实现分析
2019/07/19 Javascript
jQuery中getJSON跨域原理的深入讲解
2020/09/02 jQuery
python实现TCP服务器端与客户端的方法详解
2015/04/30 Python
python使用正则表达式的search()函数实现指定位置搜索功能
2017/11/10 Python
python pandas dataframe 行列选择,切片操作方法
2018/04/10 Python
python获取酷狗音乐top500的下载地址 MP3格式
2018/04/17 Python
python实现log日志的示例代码
2018/04/28 Python
迪梵英国官方网站:Darphin英国
2017/12/06 全球购物
摩托车和ATV零件、配件和服装的首选在线零售商:MotoSport
2017/12/22 全球购物
美国五金商店:Ace Hardware
2018/03/27 全球购物
名人珠宝设计师:Melinda Maria Jewelry
2019/03/06 全球购物
到底Java是如何传递参数的?是by value或by reference?
2012/07/13 面试题
党员批评与自我批评
2014/02/12 职场文书
招聘专员岗位职责
2014/03/07 职场文书
班级标语大全
2014/06/21 职场文书
2014年团队工作总结
2014/11/24 职场文书
体育个人工作总结
2015/02/09 职场文书
2015年机械设备管理工作总结
2015/05/04 职场文书
节水宣传标语口号
2015/12/26 职场文书
Python+Appium新手教程
2021/04/17 Python
python入门学习关于for else的特殊特性讲解
2021/11/20 Python