回首页

octobercms 启动分析

octobercms 是构建在laravel的基础上的

入口文件

index.php

可以看到入口文件的内容和laravel的是一样的。比较重要的是bootstrap/app.php 文件

<?php

/*
|--------------------------------------------------------------------------
| Create The Application
|--------------------------------------------------------------------------
|
| The first thing we will do is create a new Laravel application instance
| which serves as the "glue" for all the components of Laravel, and is
| the IoC container for the system binding all of the various parts.
|
*/

$app = new October\Rain\Foundation\Application(
    realpath(__DIR__.'/../')
);

/*
|--------------------------------------------------------------------------
| Bind Important Interfaces
|--------------------------------------------------------------------------
|
| Next, we need to bind some important interfaces into the container so
| we will be able to resolve them when needed. The kernels serve the
| incoming requests to this application from both the web and CLI.
|
*/

$app->singleton(
    Illuminate\Contracts\Http\Kernel::class,
    October\Rain\Foundation\Http\Kernel::class
);

$app->singleton(
    Illuminate\Contracts\Console\Kernel::class,
    October\Rain\Foundation\Console\Kernel::class
);

$app->singleton(
    Illuminate\Contracts\Debug\ExceptionHandler::class,
    October\Rain\Foundation\Exception\Handler::class
);

/*
|--------------------------------------------------------------------------
| Return The Application
|--------------------------------------------------------------------------
|
| This script returns the application instance. The instance is given to
| the calling script so we can separate the building of the instances
| from the actual running of the application and sending responses.
|
*/

return $app;

可以看到octobercms 重写了 laravel 的容器 Illuminate\Foundation\Application October\Rain\Foundation\Application继承 Illuminate\Foundation\Application October\Rain\Foundation\Http\Kernel继承 Illuminate\Foundation\Http\Kernel http请求先经过这里 October\Rain\Foundation\Console\Kernel继承Illuminate\Foundation\Console\Kernel 命令行处理

October\Rain\Foundation\Exception\Handler继承Illuminate\Foundation\Exceptions\Handler 错误处理

先看

$app = new October\Rain\Foundation\Application(
    realpath(__DIR__.'/../')
);

做了哪些事情

没有重写构造函数,还是这样

public function __construct($basePath = null)
{
    if ($basePath) {
    $this->setBasePath($basePath);
    }
    $this->registerBaseBindings();//绑定app实例即自身到容器中
    $this->registerBaseServiceProviders();//注册服务提供者
    $this->registerCoreContainerAliases();
}

October\Rain\Foundation\Application可以看到只重写了registerBaseServiceProviders函数

protected function registerBaseServiceProviders()
    {
        $this->register(new EventServiceProvider($this));//和laravel的一样

        $this->register(new LogServiceProvider($this));//和laravel测一样只是更改了日志的文件路径

        $this->register(new RoutingServiceProvider($this));//注册了一个路由前置事件和后置事件

        $this->register(new MakerServiceProvider($this));
    }

路由事件 重写了dispatch方法重要,添加个路由前置事件,把所需的路由注册进去 October\Rain\Router\CoreRouter

public function dispatch(Request $request)
    {
        $this->currentRequest = $request;

        $this->events->fire('router.before', [$request]);//前置事件,注册路由在modules/backend/routes.php中

        $response = $this->dispatchToRoute($request);

        $this->events->fire('router.after', [$request, $response]);//后置事件

        return $response;
    }

上面的和laravel都是大同小异主要看下面,octobercms怎么把请求送到你的业务代码的


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

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

$kernel 是这个类October\Rain\Foundation\Http\Kernel的实例

<?php namespace October\Rain\Foundation\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    /**
     * The bootstrap classes for the application.
     *
     * @var array
     */
    protected $bootstrappers = [
        '\October\Rain\Foundation\Bootstrap\RegisterClassLoader',//加载plugin和modules 下面的类
        '\October\Rain\Foundation\Bootstrap\LoadEnvironmentVariables',//加载env配置
        '\October\Rain\Foundation\Bootstrap\LoadConfiguration',//加载config下的配置
        '\October\Rain\Foundation\Bootstrap\LoadTranslation',
        \Illuminate\Foundation\Bootstrap\HandleExceptions::class,
        \Illuminate\Foundation\Bootstrap\RegisterFacades::class,
        '\October\Rain\Foundation\Bootstrap\RegisterOctober',//注册octobercms提供
        \Illuminate\Foundation\Bootstrap\RegisterProviders::class,
        \Illuminate\Foundation\Bootstrap\BootProviders::class,
    ];

    /**
     * The application's global HTTP middleware stack.
     *
     * @var array
     */
    protected $middleware = [
        'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
    ];

    /**
     * The application's route middleware.
     *
     * @var array
     */
    protected $routeMiddleware = [
        // 'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
        // 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        // 'can' => \Illuminate\Auth\Middleware\Authorize::class,
        // 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    ];

    /**
     * The application's route middleware groups.
     *
     * @var array
     */
    protected $middlewareGroups = [
        'web' => [
            \October\Rain\Cookie\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            // \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
        'api' => [
            'throttle:60,1',
            'bindings',
        ],
    ];

    /**
     * The priority-sorted list of middleware.
     *
     * Forces the listed middleware to always be in the given order.
     *
     * @var array
     */
    protected $middlewarePriority = [
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        // \Illuminate\Auth\Middleware\Authenticate::class,
        // \Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
        // \Illuminate\Auth\Middleware\Authorize::class,
    ];
}

可以看到octobercms提供了自己的一些启动文件,并取消了laravel的一些启动项,接下里和laravel是一样的,去找对应的控制器运行相应的方法

那么octobercms的路由在哪里呢, 后台路由可以再 module/backend/routes.php 看到

<?php

/**
 * Register Backend routes before all user routes.
 */
App::before(function ($request) {
    /*
     * Extensibility
     */
    Event::fire('backend.beforeRoute');

    /*
     * Other pages
     */
    Route::group([
            'middleware' => ['web'],
            'prefix' => Config::get('cms.backendUri', 'backend')
        ], function () {
            Route::any('{slug}', 'Backend\Classes\BackendController@run')->where('slug', '(.*)?');
        })
    ;

    /*
     * Entry point
     */
    Route::any(Config::get('cms.backendUri', 'backend'), 'Backend\Classes\BackendController@run')->middleware('web');

    /*
     * Extensibility
     */
    Event::fire('backend.route');
});

看到octobercms把所有后台的路由映射到了控制器Backend\Classes\BackendControllerrun方法,就像执行laravel的方法一样,只不过这个方法里面有octobercms自己的一套逻辑