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 相关文章推荐
第五节 克隆 [5]
Oct 09 PHP
PHP+.htaccess实现全站静态HTML文件GZIP压缩传输(一)
Feb 15 PHP
php结合表单实现一些简单功能的例子
Jun 04 PHP
PHP扩展模块memcached长连接使用方法分析
Dec 24 PHP
codeigniter中实现一次性加载多个view的方法
Mar 20 PHP
php获取网页上所有链接的方法
Apr 03 PHP
百度工程师讲PHP函数的实现原理及性能分析(二)
May 13 PHP
CI框架实现cookie登陆的方法详解
May 18 PHP
php获取远程图片并下载保存到本地的方法分析
Oct 08 PHP
PHP实践教程之过滤、验证、转义与密码详解
Jul 24 PHP
php简单检测404页面的方法示例
Aug 23 PHP
Thinkphp 框架扩展之数据库驱动常用方法小结
Apr 23 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中判断一个字符串包含另一个字符串的方法
2007/03/19 PHP
PHP常用代码大全(新手入门必备)
2010/06/29 PHP
php购物车实现代码
2011/10/10 PHP
php从右向左/从左向右截取字符串的实现方法
2011/11/28 PHP
php中url函数介绍及使用示例
2014/02/13 PHP
thinkphp特殊标签用法概述
2014/11/24 PHP
php输出全球各个时区列表的方法
2015/03/31 PHP
PHP中Trait及其应用详解
2017/02/14 PHP
简单JS代码压缩器
2006/10/12 Javascript
让JavaScript 轻松支持函数重载 (Part 1 - 设计)
2009/08/04 Javascript
脚本合并提升javascript性能示例
2014/02/24 Javascript
轻松创建nodejs服务器(10):处理POST请求
2014/12/18 NodeJs
jQuery+jsp下拉框联动获取本地数据的方法(附源码)
2015/12/03 Javascript
利用D3.js实现最简单的柱状图示例代码
2016/12/09 Javascript
Vue多种方法实现表头和首列固定的示例代码
2018/02/02 Javascript
Vue项目webpack打包部署到Tomcat刷新报404错误问题的解决方案
2018/05/15 Javascript
Python 解析XML文件
2009/04/15 Python
Python 自动安装 Rising 杀毒软件
2009/04/24 Python
python使用7z解压软件备份文件脚本分享
2014/02/21 Python
Python中的字典与成员运算符初步探究
2015/10/13 Python
pandas修改DataFrame列名的方法
2018/04/08 Python
django利用request id便于定位及给日志加上request_id
2018/08/26 Python
Python基于机器学习方法实现的电影推荐系统实例详解
2019/06/25 Python
Python tcp传输代码实例解析
2020/03/18 Python
Python面向对象程序设计之类和对象、实例变量、类变量用法分析
2020/03/23 Python
解决django xadmin主题不显示和只显示bootstrap2的问题
2020/03/30 Python
python如何实现DES加密
2020/09/21 Python
一个J2EE项目团队的主要人员组成是什么
2012/06/04 面试题
顺丰快递Java软件工程师面试题
2015/07/31 面试题
运动会入场词100字
2014/02/06 职场文书
《卖木雕的少年》教学反思
2014/04/11 职场文书
个人融资协议书
2014/10/02 职场文书
初中生思想道德自我评价
2015/03/09 职场文书
源码解读Spring-Integration执行过程
2021/06/11 Java/Android
python opencv检测直线 cv2.HoughLinesP的实现
2021/06/18 Python
CSS实现两列布局的N种方法
2021/08/02 HTML / CSS