laravel解析-入口应用初始化

这篇博客详细解析了laravel框架的单一入口模式,从public/index.php开始,逐行解释了启动过程。首先定义启动时间,接着加载composer的autoload文件以加载所需依赖。然后实例化了$app应用对象,通过app.php文件完成了路径设置、服务提供者注册、核心类别名绑定等工作。在kernel处理请求之前,应用完成了环境检测、配置加载、日志配置、异常处理、门面注册和服务提供者的注册与启动。最后,通过kernel的handle方法处理HTTP请求,通过一系列中间件完成路由和控制器的调用,返回响应给浏览器。
摘要由CSDN通过智能技术生成

laravel是单一入口模式,所有请求从public/index.php进入

define('LARAVEL_START', microtime(true));


require __DIR__.'/../vendor/autoload.php';


$app = require_once __DIR__.'/../bootstrap/app.php';

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);

$response->send();

$kernel->terminate($request, $response);

 我们都知道 web程序做的事情就是:

1.用户从浏览器发送请求,请求

2.程序接收请求进行计算,网页程序

3.运算结果返回给浏览器,网页响应

index文件中的$request $kernel $resopnse 就是对应着请求、计算、响应

请求部分使用syfmony的request组件对刘篮球发出的请求头信息进行打包收集,形成一个对象来方便我们操作

$kernel算是laravel的请求处理核心了,通过request里的url找到相应路由的控制器,

执行后返回视图等响应,并将$response输出至浏览器。

步骤解析

第一步:define('LARAVEL_START', microtime(true));

        首先计算启动框架的时间,但是在整个生命周期里面却没有用到过

第二步:require __DIR__.'/../vendor/autoload.php';

       这行代码引入了composer启动文件,PHP所需要的文件,都需要在这里加载,laravel有一个composer.json文件,写入了我们需要的依赖,composer启动的时候,会把这些依赖缓存成key/value数组,出发spl_autoload函数进行加载

第三步:$app = require_once __DIR__.'/../bootstrap/app.php';

       这行数据实例化了一个$app的应用程序对象,这是个关键,让我们看一下这个文件

<?php
$app = new Illuminate\Foundation\Application(
    realpath(__DIR__.'/../')
);

$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
);

return $app;

它做的事情不多 显示实例化了一个application对象,然后把http和控制台kernel还有异常处理实例绑定到了这个对象中,返回给了index文件

我们来解析一下实例化application对象的过程

public function __construct($basePath = null)
    {
        if ($basePath) {
            $this->setBasePath($basePath);
        }

        $this->registerBaseBindings();

        $this->registerBaseServiceProviders();


        $this->registerCoreContainerAliases();
    }

构造函数做了下面的四件事:

第一件:

      加载了项目的一些路径存储到了$app对象里面,我们查看setBasePath方法

public function setBasePath($basePath)
    {
        $this->basePath = rtrim($basePath, '\/');

        $this->bindPathsInContainer();

        return $this;
    }

在查看bindPathsInContainer方法

protected function bindPathsInContainer()
    {
        $this->instance('path', $this->path());
        $this->instance('path.base', $this->basePath());
        $this->instance('path.lang', $this->langPath());
        $this->instance('path.config', $this->configPath());
        $this->instance('path.public', $this->publicPath());
        $this->instance('path.storage', $this->storagePath());
        $this->instance('path.database', $this->databasePath());
        $this->instance('path.resources', $this->resourcePath());
        $this->instance('path.bootstrap', $this->bootstrapPath());
    }

具体的实现代码在其父类Container类的instance方法中,代码很简单就一句是$this->instances[$abstract] = $instance;。

 public function instance($abstract, $instance)
    {
        $this->removeAbstractAlias($abstract);

        $isBound = $this->bound($abstract);

        unset($this->aliases[$abstract]);

        // We'll check to determine if this type has been bound before, and if it has
        // we will fire the rebound callbacks registered with the container and it
        // can be updated with consuming classes that have gotten resolved here.
        $this->instances[$abstract] = $instance;

        if ($isBound) {
            $this->rebound($abstract);
        }

        return
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值