Laravel架构分析

admin 2022年4月20日00:49:25评论68 views字数 4207阅读14分1秒阅读模式

Laravel介绍

Laravel是一款开源的PHP框架,在全球范围内有着众多用户,也有很多基于此框架开发的开源CMS。该框架在国外很受欢迎,国外用户量远大于国内。当然,国内也有大型企业使用该框架。
Laravel历史上也爆出过一些漏洞,比如CVE-2018-15133(TOKEN反序列化漏洞)、信息泄漏、5.8版本的SQL注入、Debug RCE等,还有一些未被收入CVE的反序列化链。

Laravel架构分析

目录结构

app/ 核心文件夹,包括controllermodlemiddleware等各种核心文件
./Console/ 用于处理cli的请求,包括所有自定义的Artisan命令
./Http/ 用于处理http请求
./Controllers/ 控制器文件
./Middleware/ 中间件文件
./Requests/
...
./Kernel.php 定义中间件的别名映射、创建中间件组,比如web、api中间件组。
./Exceptions/ 异常处理类
./Providers/ 服务提供者&其他provider(详见provider目录)
bootstrap/ laravel框架加载器
cache/ 缓存
config/ 应用配置文件
./app.php 定义providers和alias,以及一些全局配置。比如debug等等。
...
html/ 程序入口和静态资源文件。业务逻辑尽量不写在这里。
index.php 程序入口。
routes/ 路由定义文件,每个路由文件都分别给不同的入口使用
./web.php 其中的路由都被web中间件组(middleware group)所约束。
./api.php 其中的路由都被api中间件组所约束。
./console.php
./channels.php
resources/ 静态资源文件
./views/
xxx.blade.php View文件
vendor/ 第三方库文件
./laravel/

常用命令

常见项目:
composer create-project laravel/laravel laravel_6_18_8 "v6.18.8”
快速查看Laravel版本号:
vendor/laravel/framework/src/Illuminate/Foundation/Application.php
创建控制器:
php artisan make:controller test123
开启web服务:
php artisan serve
Laravel架构分析

几个关键组件

Middleware

middleware在代码执行顺序中,主要位于路由调度与控制器之间,类似于preAction()。
middleware在目录结构中说了,位于app/Http/Middleware/目录下,比如librenms中有个middleware是CheckInstalled,关键代码如下:
<?php
namespace AppHttpMiddleware;
use Closure;
class CheckInstalled{
/**
* Handle an incoming request.
* @param IlluminateHttpRequest $request
* @param Closure $next
* @return mixed
*/
public function handle($request, Closure $next){
if (!file_exists(base_path('config.php')) && !$request->is('install.php')) {
return redirect(url('/install.php')); //重定向
}
return $next($request); //传给下一个中间件
}}

容器

laravel容器一般这样初始化:
$app = new IlluminateFoundationApplication(
dirname(__DIR__)
);
服务绑定与解析,有如下的方法:
$this->app->bind('service1', function(){
return new Service1();
}); //绑定注册service1
$ser1 = $this->app->make('service1'); //解析service1服务,创建service1 class实例
$this->app->singleton('service2', function(){
return new Service2();
}); //单例模式绑定service2
$ser2 = $this->app->make('service2'); //程序中无论调用多少次make(),都只有一个service2 class实例。

Provider

provider有两种,一种是service provider,服务提供者,用于将服务绑定到容器上。
还有一种是普通provider,这类provider一般可能是为了其他组件服务的,比如service provider、guard等。
laravel提供了这类的provider接口,比如laravel/framework/src/Illuminate/Contracts/Auth/UserProvider.php,开发者可以选择实现这个接口,然后来实现自己的功能,从接口定义的方法就可以看出来这个provider的用法。
<?php
namespace IlluminateContractsAuth;
interface UserProvider
{
public function retrieveById($identifier);
public function retrieveByToken($identifier, $token);
public function updateRememberToken(Authenticatable $user, $token);
public function retrieveByCredentials(array $credentials);
public function validateCredentials(Authenticatable $user, array $credentials);
}
而对于第一种的服务提供者,命名格式通常为xxxServiceProvider.php,另一类provider格式通常为xxProvider.php。
服务提供者在config/app.php中被providers列表加载。服务提供者用于将一个类/实例....绑定到容器上,也就是上面说的bind()、singleton()等方法。
服务提供者主要是为了依赖注入而存在的。看如下控制器代码:
<?php
namespace AppHttpControllers;
class Test222{
public $name;
public function __construct() {
$this->name = 'kkk';
}}
class Test111{
public $app;
public function __construct(Test222 $app) {
$this->app = $app;
}}
class test1 extends Controller{
public function hello2(){
app()->bind(Test222::class);//注册Test222
app()->bind(Test111::class);//注册Test111
$aa = app()->make(Test111::class);//解析Test111
var_dump($aa);
}}
访问这个控制器
Laravel架构分析
这里在实例化Test111时,由于其中有对Test222的依赖,laravel会去寻找注册的名为Test222的服务名,也就是前面bind()/singleton()等方法绑定的服务。
最终使用app()->make()来获取一个Test111实例,而未手动传入任何参数比如new Test111(new Test222());。
Laravel架构分析

路由

路由配置

路由设置无非就是两个文件,route/web.php和route/api.php。文件中也可以自己设置一些middleware。
比如:
<?php
Auth::routes();
// WebUI
Route::group(['middleware' => ['auth', '2fa'], 'guard' => 'auth'], function () {//绑定auth和2fa中间件
Route::get('/vue/{sub?}', function () {
return view('vue');
})->where('sub', '.*');
Route::resource('device-groups', 'DeviceGroupController');
Route::get('poller', 'PollerController@pollerTab')->name('poller'); //GET路由
Route::get('/hello', "AppHttpControllerstest123@YourFunName");
Route::get('locations', 'LocationController@index');
Route::resource('preferences', 'UserPreferencesController', ['only' => ['index', 'store']]);
Route::resource('users', 'UserController');
Route::get('about', 'AboutController@index');
Route::get('authlog', 'UserController@authlog');
});

路由调度

先从route/目录下的路由文件中找到匹配的路由,然后找到其对应的中间件组。web.php中的路由对应web中间件组,api.php同理。web.php和api.php中也可以自定义一些中间件。
找到所有的中间件组之后,按照一定的顺序,先后调用这些中间件,其中的传参就是Illuminate/Http/Request实例,其中就是我们请求的一些信息。
经过所有的middleware之后,最终才会到达控制器。
Laravel架构分析

Laravel架构分析

原文始发于微信公众号(山石网科安全技术研究院):Laravel架构分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年4月20日00:49:25
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Laravel架构分析http://cn-sec.com/archives/926501.html

发表评论

匿名网友 填写信息