Laravel源碼入門-啓動引導過程(六)LoadEnvironmentVariables

上篇:Laravel源碼入門-啓動引導過程(五)$kernel->handle($request)

第一個要載入的是 LoadEnvironmentVariables,也就是 Foundation\Http\Kernel::bootstrapers[] 的第一個,\Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables,如下:

 

// Illuminate\Foundation\Http\Kernel.php 片段

   /**
     * The bootstrap classes for the application.
     * 引導類,起引導作用的類
     *
     * @var array
     */
    protected $bootstrappers = [
        // 載入服務器環境變量(.env 文件)
        \Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class,
        // 載入配置信息(config 目錄)
        \Illuminate\Foundation\Bootstrap\LoadConfiguration::class,
        // 配置如何處理異常
        \Illuminate\Foundation\Bootstrap\HandleExceptions::class,
        // 註冊 Facades
        \Illuminate\Foundation\Bootstrap\RegisterFacades::class,
        // 註冊 Providers
        \Illuminate\Foundation\Bootstrap\RegisterProviders::class,
        // 啓動 Providers
        \Illuminate\Foundation\Bootstrap\BootProviders::class,
    ];

我們再直接貼出 LoadEnvironmentVariables 類的代碼,進行分析,非常直觀,如下:

<?php // Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables.php 代碼

namespace Illuminate\Foundation\Bootstrap;

// phpdotenv:一個程序包,文件夾中搜索可以找到,自動把 .env 文件的內容載入 $_ENV和$_SERVER
use Dotenv\Dotenv;
use Dotenv\Exception\InvalidPathException;
use Symfony\Component\Console\Input\ArgvInput;
use Illuminate\Contracts\Foundation\Application;

class LoadEnvironmentVariables
{
    /**
     * Bootstrap the given application.
     * 引導指定$app,這裏是注入依賴方式
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @return void
     */
    public function bootstrap(Application $app)
    {
        if ($app->configurationIsCached()) {
            return;
        }

        $this->checkForSpecificEnvironmentFile($app);

        try {
            // 這裏語句分兩部分,new 一個 Dotenv 對象,該對象調用 load() 方法,
            // 載入了根目錄 .env 文件的配置。
            (new Dotenv($app->environmentPath(), $app->environmentFile()))->load();
        } catch (InvalidPathException $e) {
            //
        }
    }

    /**
     * Detect if a custom environment file matching the APP_ENV exists.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @return void
     */
    protected function checkForSpecificEnvironmentFile($app)
    {
        if (php_sapi_name() == 'cli' && with($input = new ArgvInput)->hasParameterOption('--env')) 
        {
            $this->setEnvironmentFilePath(
                $app, $app->environmentFile().'.'.$input->getParameterOption('--env')
            );
        }

        if (! env('APP_ENV')) {
            return;
        }

        $this->setEnvironmentFilePath(
            $app, $app->environmentFile().'.'.env('APP_ENV')
        );
    }

    /**
     * Load a custom environment file.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @param  string  $file
     * @return void
     */
    protected function setEnvironmentFilePath($app, $file)
    {
        if (file_exists($app->environmentPath().'/'.$file)) {
            $app->loadEnvironmentFrom($file);
        }
    }
}

完成後,我們就可以使用Laravel提供的幫助函數 env() 來獲取環境變量的值,如 dump(env('APP_URL'))。

附1:這裏有一個細微的問題,就是 .env 文件中有一個配置項 APP_ENV=local,因此,應該將 .env 文件改名爲 .env.local 也可以讀取到該文件。但如果在  APP_ENV=local 的情況下,把 名字改爲其他的,如 .env.localxx,就會出錯,報   catch (InvalidPathException $e)  錯誤,當然 Laravel 沒有寫出報錯的提示語。

附2:置於爲什麼有這個 .env?一開始,我也沒有質疑,無所謂的樣子,但實際是 Lavravl 的一個團隊協作的考慮,具體參見:《關於 Laravel 項目裏的 .env 文件的使用》。

附3:Laravel的幫助函數都位於 vendor/laravel/framework/src/Illuminate/Foundation/helpers.php。

附4:.env 中包含了重要配置,比如數據庫mysql 的配置,開發提前設置,但團隊開發請注意附2。

下篇:Laravel源碼入門-啓動引導過程(七)LoadConfiguration

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章