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 和 MySQL 基础教程(三)
Oct 09 PHP
PHP 字符串操作入门教程
Dec 06 PHP
PHP模块 Memcached功能多于Memcache
Jun 14 PHP
PHP ? EasyUI DataGrid 资料存的方式介绍
Nov 07 PHP
PHP设置图片文件上传大小的具体实现方法
Oct 11 PHP
php实现图片局部打马赛克的方法
Feb 11 PHP
Yii2 输出xml格式数据的方法
May 03 PHP
微信公众号OAuth2.0网页授权问题浅析
Jan 21 PHP
php 基础函数
Feb 10 PHP
php pdo操作数据库示例
Mar 10 PHP
bindParam和bindValue的区别以及在Yii2中的使用详解
Mar 12 PHP
从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解
Apr 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
颠覆常识!无色透明的咖啡诞生了(中日双语)
2021/03/03 咖啡文化
如何在PHP程序中防止盗链
2008/04/09 PHP
PHP4中session登录页面的应用
2008/07/25 PHP
php全局变量和类配合使用深刻理解
2013/06/05 PHP
php设计模式之单例模式使用示例
2014/01/20 PHP
php导入模块文件分享
2015/03/17 PHP
php将字符串转换成16进制的方法
2015/03/17 PHP
对 lightbox JS 图片控件进行了一下改造, 使其他支持复杂的图片说明
2010/03/20 Javascript
AlertBox 弹出层信息提示框效果实现步骤
2010/10/11 Javascript
70+漂亮且极具亲和力的导航菜单设计国外网站推荐
2011/09/20 Javascript
angularJS结合canvas画图例子
2015/02/09 Javascript
JS使用eval()动态创建变量的方法
2016/06/03 Javascript
仅一个form表单 js实现注册信息依次填写提交功能
2016/06/12 Javascript
JS防止网页被嵌入iframe框架的方法分析
2016/09/13 Javascript
vue.js表格组件开发的实例详解
2016/10/12 Javascript
详谈Ajax请求中的async:false/true的作用(ajax 在外部调用问题)
2017/02/10 Javascript
实例详解display:none与visible:hidden的区别
2017/03/30 Javascript
webpack学习笔记之代码分割和按需加载的实例详解
2017/07/20 Javascript
基于vue-video-player自定义播放器的方法
2018/03/21 Javascript
Vue列表渲染的示例代码
2018/11/01 Javascript
NodeJs实现简易WEB上传下载服务器
2019/08/10 NodeJs
vue iview 隐藏Table组件里的某一列操作
2020/11/13 Javascript
python轻松查到删除自己的微信好友
2016/01/10 Python
Python可变参数*args和**kwargs用法实例小结
2018/04/27 Python
wtfPython—Python中一组有趣微妙的代码【收藏】
2018/08/31 Python
Python对象中__del__方法起作用的条件详解
2018/11/01 Python
Python 类属性与实例属性,类对象与实例对象用法分析
2019/09/20 Python
在子网210.27.48.21/30种有多少个可用地址?分别是什么?
2014/07/27 面试题
车辆维修工自我评价怎么写
2013/09/20 职场文书
优秀少先队工作者事迹材料
2014/05/13 职场文书
小学学习雷锋活动总结
2014/07/03 职场文书
小学中等生评语
2014/12/29 职场文书
小平您好观后感
2015/06/09 职场文书
教师读书笔记
2015/06/29 职场文书
MySQL 角色(role)功能介绍
2021/04/24 MySQL
python模拟浏览器 使用selenium进入好友QQ空间并留言
2022/04/12 Python