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 相关文章推荐
phpMyAdmin 安装教程全攻略
Mar 19 PHP
php 变量定义方法
Jun 14 PHP
php 小乘法表实现代码
Jul 16 PHP
PHP实现今天是星期几的几种写法
Sep 26 PHP
PHP URL路由类实例
Nov 12 PHP
php 判断字符串中是否包含html标签
Feb 17 PHP
DOM基础及php读取xml内容操作的方法
Jan 23 PHP
php生成固定长度纯数字编码的方法
Jul 09 PHP
YII Framework框架教程之缓存用法详解
Mar 14 PHP
PHP更安全的密码加密机制Bcrypt详解
Jun 18 PHP
PHP消息队列实现及应用详解【队列处理订单系统和配送系统】
May 20 PHP
PHP7创建COOKIE和销毁COOKIE的实例方法
Feb 03 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
递归列出所有文件和目录
2006/10/09 PHP
采用memcache在web集群中实现session的同步会话
2014/07/05 PHP
php实现遍历文件夹的方法汇总
2017/03/02 PHP
PHP实现动态添加XML中数据的方法
2018/03/30 PHP
PHP给前端返回一个JSON对象的实例讲解
2018/05/31 PHP
Yii2.0建立公共方法简单示例
2019/01/29 PHP
javascript中巧用“闭包”实现程序的暂停执行功能
2007/04/04 Javascript
深入理解JavaScript系列(6):S.O.L.I.D五大原则之单一职责SRP
2012/01/15 Javascript
使用Chrome浏览器调试AngularJS应用的方法
2015/06/18 Javascript
jquery validate和jquery form 插件组合实现验证表单后AJAX提交
2015/08/26 Javascript
基于jquery实现智能表单验证操作
2016/05/09 Javascript
JQuery Ajax 异步操作之动态添加节点功能
2017/05/24 jQuery
详谈表单格式化插件jquery.serializeJSON
2017/06/23 jQuery
XMLHttpRequest对象_Ajax异步请求重点(推荐)
2017/09/28 Javascript
node跨域转发 express+http-proxy-middleware的使用
2018/05/31 Javascript
JS实现获取毫秒值及转换成年月日时分秒的方法
2018/08/15 Javascript
bootstrap自定义样式之bootstrap实现侧边导航栏功能
2018/09/10 Javascript
微信小程序实现带参数的分享功能(两种方法)
2019/05/17 Javascript
20个必会的JavaScript面试题(小结)
2019/07/02 Javascript
浅谈Vue.js之初始化el以及数据的绑定说明
2019/11/14 Javascript
vue 实现websocket发送消息并实时接收消息
2019/12/09 Javascript
Vue绑定用户接口实现代码示例
2020/11/04 Javascript
[01:24:51]2014 DOTA2华西杯精英邀请赛 5 25 LGD VS NewBee第二场
2014/05/26 DOTA
[50:50]完美世界DOTA2联赛PWL S3 Galaxy Racer vs Phoenix 第一场 12.10
2020/12/13 DOTA
Python函数中*args和**kwargs来传递变长参数的用法
2016/01/26 Python
python中如何正确使用正则表达式的详细模式(Verbose mode expression)
2017/11/08 Python
对Python3.x版本print函数左右对齐详解
2018/12/22 Python
从列表或字典创建Pandas的DataFrame对象的方法
2019/07/06 Python
CSS3制作轮播图的一种方法
2019/11/11 HTML / CSS
小狗电器官方商城:中国高端吸尘器品牌
2017/03/29 全球购物
可打印的优惠券、杂货和优惠券代码:Coupons.com
2018/06/12 全球购物
Sunglass Hut巴西网上商店:男女太阳镜
2020/10/04 全球购物
《埃及的金字塔》教学反思
2014/04/07 职场文书
2015年转正工作总结范文
2015/04/02 职场文书
Python selenium绕过webdriver监测执行javascript
2022/04/12 Python
前端传参数进行Mybatis调用mysql存储过程执行返回值详解
2022/08/14 MySQL