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 相关文章推荐
php读取xml实例代码
Jan 28 PHP
php数组函数序列之array_intersect() 返回两个或多个数组的交集数组
Nov 10 PHP
php获取Google机器人访问足迹的方法
Apr 15 PHP
PHP数组和explode函数示例总结
May 08 PHP
PHP设计模式之适配器模式代码实例
May 11 PHP
PHP测试成功的邮件发送案例
Oct 26 PHP
PHP中addcslashes与stripcslashes函数用法分析
Jan 07 PHP
php结合web uploader插件实现分片上传文件
May 10 PHP
PHP输出XML格式数据的方法总结
Feb 08 PHP
PHP mysqli事务操作常用方法分析
Jul 22 PHP
ThinkPHP5+UEditor图片上传到阿里云对象存储OSS功能示例
Aug 05 PHP
Laravel 不同生产环境服务器的判断实践
Oct 15 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
漫荒推荐:画风超赞的国风漫画推荐 超长假期不无聊
2020/03/08 国漫
天津市收音机工业发展史
2021/03/04 无线电
php cookie 登录验证示例代码
2009/03/16 PHP
用PHP查询搜索引擎排名位置的代码
2010/01/05 PHP
PHP中用接口、抽象类、普通基类实现“面向接口编程”与“耦合方法”简述
2011/03/23 PHP
PHP入门教程之数学运算技巧总结
2016/09/11 PHP
laravel 数据迁移与 Eloquent ORM的实现方法
2019/04/12 PHP
用js实现随机返回数组的一个元素
2007/08/13 Javascript
fckeditor 获取文本框值的实现代码
2009/02/09 Javascript
js 数组实现一个类似ruby的迭代器
2009/10/27 Javascript
浅析offsetLeft,Left,clientLeft之间的区别
2013/11/30 Javascript
浅析document.ready和window.onload的区别讲解
2013/12/18 Javascript
ie 7/8不支持trim的属性的解决方案
2014/05/23 Javascript
js实现图片轮播效果
2015/12/19 Javascript
javaScript知识点总结(必看篇)
2016/06/10 Javascript
JS取数字小数点后两位或n位的简单方法
2016/10/24 Javascript
Vue.js第二天学习笔记(vue-router)
2016/12/01 Javascript
js绑定事件和解绑事件
2017/04/27 Javascript
JavaScript变量作用域_动力节点Java学院整理
2017/06/27 Javascript
vue用addRoutes实现动态路由的示例
2017/09/15 Javascript
bootstrap Table的一些小操作
2017/11/01 Javascript
JavaScript中使用import 和require打包后实现原理分析
2018/03/07 Javascript
详解解决使用axios发送json后台接收不到的问题
2018/06/27 Javascript
微信小程序JS加载esmap地图的实例详解
2019/09/04 Javascript
vue项目接口管理,所有接口都在apis文件夹中统一管理操作
2020/08/13 Javascript
详细讲解用Python发送SMTP邮件的教程
2015/04/29 Python
Django中更改默认数据库为mysql的方法示例
2018/12/05 Python
Flask-WTF表单的使用方法
2019/07/12 Python
Python实现剪刀石头布小游戏(与电脑对战)
2019/12/31 Python
手把手教你进行Python虚拟环境配置教程
2020/02/03 Python
python GUI库图形界面开发之PyQt5信号与槽基础使用方法与实例
2020/03/06 Python
Python生成pdf目录书签的实例方法
2020/10/29 Python
Python常用外部指令执行代码实例
2020/11/05 Python
学校爱国卫生月活动总结
2014/06/25 职场文书
农林经济管理专业自荐信
2014/09/01 职场文书
Mysql Online DDL的使用详解
2021/05/20 MySQL