Laravel介绍
Laravel是一款开源的PHP框架,在全球范围内有着众多用户,也有很多基于此框架开发的开源CMS。该框架在国外很受欢迎,国外用户量远大于国内。当然,国内也有大型企业使用该框架。
Laravel历史上也爆出过一些漏洞,比如CVE-2018-15133(TOKEN反序列化漏洞)、信息泄漏、5.8版本的SQL注入、Debug RCE等,还有一些未被收入CVE的反序列化链。
![PHP开源框架Laravel架构分析 PHP开源框架Laravel架构分析]()
目录结构
app/ 核心文件夹,包括controllermodlemiddleware等各种核心文件
./Console/ 用于处理cli的请求,包括所有自定义的Artisan命令
./Kernel.php 定义中间件的别名映射、创建中间件组,比如web、api中间件组。
./Providers/ 服务提供者&其他provider(详见provider目录)
./app.php 定义providers和alias,以及一些全局配置。比如debug等等。
html/ 程序入口和静态资源文件。业务逻辑尽量不写在这里。
routes/ 路由定义文件,每个路由文件都分别给不同的入口使用
./web.php 其中的路由都被web中间件组(middleware group)所约束。
./api.php 其中的路由都被api中间件组所约束。
常用命令
composer create-project laravel/laravel laravel_6_18_8 "v6.18.8”
vendor/laravel/framework/src/Illuminate/Foundation/Application.php
php artisan make:controller test123
开启web服务:
php artisan serve
几个关键组件
Middleware
middleware在代码执行顺序中,主要位于路由调度与控制器之间,类似于preAction()。
middleware在目录结构中说了,位于app/Http/Middleware/目录下,比如librenms中有个middleware是CheckInstalled,关键代码如下:
namespace AppHttpMiddleware;
* Handle an incoming request.
* @param IlluminateHttpRequest $request
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); //传给下一个中间件
容器
$app = new IlluminateFoundationApplication(
$this->app->bind('service1', function(){
$ser1 = $this->app->make('service1'); //解析service1服务,创建service1 class实例
$this->app->singleton('service2', function(){
$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的用法。
namespace IlluminateContractsAuth;
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()等方法。
服务提供者主要是为了依赖注入而存在的。看如下控制器代码:
namespace AppHttpControllers;
public function __construct() {
public function __construct(Test222 $app) {
class test1 extends Controller{
public function hello2(){
app()->bind(Test222::class);//注册Test222
app()->bind(Test111::class);//注册Test111
$aa = app()->make(Test111::class);//解析Test111
这里在实例化Test111时,由于其中有对Test222的依赖,laravel会去寻找注册的名为Test222的服务名,也就是前面bind()/singleton()等方法绑定的服务。
最终使用app()->make()来获取一个Test111实例,而未手动传入任何参数比如new Test111(new Test222());。
路由
路由配置
路由设置无非就是两个文件,route/web.php和route/api.php。文件中也可以自己设置一些middleware。
Route::group(['middleware' => ['auth', '2fa'], 'guard' => 'auth'], function () {//绑定auth和2fa中间件
Route::get('/vue/{sub?}', function () {
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之后,最终才会到达控制器。
原文始发于微信公众号(SAINTSEC):PHP开源框架Laravel架构分析
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
点赞
https://cn-sec.com/archives/3718369.html
复制链接
复制链接
-
左青龙
- 微信扫一扫
-
-
右白虎
- 微信扫一扫
-
评论