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 相关文章推荐
我的群发邮件程序
Oct 09 PHP
PHP 动态随机生成验证码类代码
Apr 09 PHP
Apache2中实现多网站域名绑定的实现方法
Jun 01 PHP
使用ThinkPHP自带的Http类下载远程图片到本地的实现代码
Aug 02 PHP
遍历指定目录下的所有目录和文件的php代码
Nov 27 PHP
PHP+jQuery 注册模块的改进(三):更新到Smarty3.1
Oct 14 PHP
php模仿asp Application对象在线人数统计实现方法
Jan 04 PHP
PHP异常处理浅析
May 12 PHP
PHP多线程模拟实现秒杀抢单
Feb 07 PHP
php处理多图上传压缩代码功能
Jun 13 PHP
php遍历目录下文件并按修改时间排序操作示例
Jul 12 PHP
php 输出缓冲 Output Control用法实例详解
Mar 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
php你的验证码安全码?
2007/01/02 PHP
探讨如何在PHP开启gzip页面压缩实例
2013/06/09 PHP
PHP实现图片上传并压缩
2015/12/22 PHP
php递归函数怎么用才有效
2018/02/24 PHP
ThinkPHP整合datatables实现服务端分页的示例代码
2018/02/10 PHP
php 读取文件夹下所有图片、文件的实例
2018/10/17 PHP
js 省地市级联选择
2010/02/07 Javascript
JavaScript中的View-Model使用介绍
2011/08/11 Javascript
基于jQuery.Validate验证库知识点的详解
2013/04/26 Javascript
jQuery中even选择器的定义和用法
2014/12/23 Javascript
用JavaScript来美化HTML的select标签的下拉列表效果
2015/11/17 Javascript
判断数组是否包含某个元素的js函数实现方法
2016/05/19 Javascript
bootstrap读书笔记之CSS组件(上)
2016/10/17 Javascript
Javascript 函数的四种调用模式
2016/11/05 Javascript
PHP7新特性简述
2017/06/11 Javascript
vue2.0的虚拟DOM渲染思路分析
2018/08/09 Javascript
vue升级之路之vue-router的使用教程
2018/08/14 Javascript
Nginx设置为Node.js的前端服务器方法总结
2019/03/27 Javascript
Vue data的数据响应式到底是如何实现的
2020/02/11 Javascript
《javascript设计模式》学习笔记三:Javascript面向对象程序设计单例模式原理与实现方法分析
2020/04/07 Javascript
Python中使用PIL库实现图片高斯模糊实例
2015/02/08 Python
python类继承用法实例分析
2015/05/27 Python
Python实现的对一个数进行因式分解操作示例
2019/06/27 Python
python pillow库的基础使用教程
2021/01/13 Python
CSS3 Backgrounds属性相关介绍
2011/05/11 HTML / CSS
IE9对HTML5中部分属性不支持的原因分析
2014/10/15 HTML / CSS
体育口号大全
2014/06/18 职场文书
小学生教师节演讲稿
2014/09/03 职场文书
2015大学生实训报告
2014/11/05 职场文书
学校世界艾滋病日宣传活动总结
2015/05/05 职场文书
2016教师节问候语
2015/11/10 职场文书
Python 如何实现文件自动去重
2021/06/02 Python
用Python将GIF动图分解成多张静态图片
2021/06/11 Python
撤回我也能看到!教你用Python制作微信防撤回脚本
2021/06/11 Python
解决Redis启动警告问题
2022/02/24 Redis