ホームページ  >  記事  >  PHPフレームワーク  >  Laravel フレームワークでの ENV の読み込みと読み込みの概要

Laravel フレームワークでの ENV の読み込みと読み込みの概要

不言
不言転載
2018-10-22 14:17:043701ブラウズ

この記事では、Laravel フレームワークでの ENV の読み込みと読み込みについて説明します。必要な方は参考にしていただければ幸いです。

Laravel は、起動時にプロジェクトに .env ファイルを読み込みます。多くの場合、アプリケーションが実行されている環境ごとに異なる構成を使用すると便利です。たとえば、テスト用の MySQL データベースをローカルで使用し、オンラインになった後、プロジェクトが自動的に運用用の MySQL データベースに切り替わるようにしたい場合があります。この記事ではenvファイルの使い方やソースコード解析について詳しく紹介します。

環境ファイルの使用

マルチ環境の環境設定

プロジェクト内の環境ファイルの数は、多くの場合、プロジェクト内の環境の数と同じです。プロジェクトに開発環境、テスト環境、運用環境がある場合は、環境に対応する .env.dev、.env.test、および .env.prod という 3 つの環境構成ファイルがプロジェクト内に存在する必要があります。 3 つのファイルの設定項目はまったく同じである必要があり、具体的な設定値は各環境のニーズに応じて設定する必要があります。

次のステップは、環境に応じてプロジェクトが異なる env ファイルをロードできるようにすることです。具体的な方法は 3 つあり、使用習慣に応じて選択できます。

環境の nginx 構成ファイルに APP_ENV 環境変数 fastcgi_param APP_ENV dev を設定します。

環境変数の環境変数を設定します。サーバー上で PHP を実行しているユーザー。たとえば、www ユーザーの /home/www/.bashrc に import APP_ENV dev

を追加し、継続的インテグレーションで cp .env.dev .env

を実行します。最初の 2 つの方法では、Laravel は env('APP_ENV') によってロードされた変数値に基づいて、対応するファイル .env.dev と .env.test をロードします。具体的には、後のソースコードでも述べますが、3番目のわかりやすい方法は、プロジェクトのデプロイ時に環境設定ファイルを.envファイルに上書きすることで、環境設定ファイルに追加の設定を行う必要がなくなります。システムとnginx。

カスタマイズされた env ファイルのパスとファイル名

env ファイルは、デフォルトでプロジェクトのルート ディレクトリに配置され、Laravel はユーザーにカスタム ENV ファイル パスを提供します。ファイル関数、

たとえば、環境パスをカスタマイズする場合は、ブートストラップ フォルダーの app.php にある Application インスタンスの useEnvironmentPath メソッドを使用できます。 env ファイル名をカスタマイズするには、ブートストラップ フォルダーの app.php にある Application インスタンスのloadEnvironmentFrom メソッドを使用できます。

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

$app->useEnvironmentPath('/customer/path')

Laravel は ENV 設定を読み込みます

Laravel ENV をロードします。これは、フレームワークがリクエストを処理する前に、ブートストラップ プロセスの LoadEnvironmentVariables フェーズで行われます。

\Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables のソースコードを見て、Laravel が env で構成をどのようにロードするかを分析してみましょう。

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

$app->loadEnvironmentFrom('customer.env')

Laravel の起動メソッドのブートストラップでは、設定がキャッシュされているかどうかを確認し、上記の環境に基づいて設定ファイルをロードする 3 つの方法のうち最初の 2 つを適用する必要があるかを決定します。 APP_ENV はシステムまたは nginx 環境変数に設定されているため、Laravel は checkForSpecificEnvironmentFile メソッドの APP_ENV の値 (.env.dev や .env.test など) に従って構成ファイルの正しい特定のパスを設定します。 3 番目のケースでは、デフォルトの .env です。詳細については、以下の checkForSpecificEnvironmentFile と関連アプリケーションの 2 つのメソッドのソース コードを参照してください:

<?php
namespace Illuminate\Foundation\Bootstrap;
use Dotenv\Dotenv;
use Dotenv\Exception\InvalidPathException;
use Symfony\Component\Console\Input\ArgvInput;
use Illuminate\Contracts\Foundation\Application;
class LoadEnvironmentVariables
{
    /**
     * Bootstrap the given application.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @return void
     */
    public function bootstrap(Application $app)
    {
        if ($app->configurationIsCached()) {
            return;
        }

        $this->checkForSpecificEnvironmentFile($app);

        try {
            (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 ($app->runningInConsole() && ($input = new ArgvInput)->hasParameterOption('--env')) {
            if ($this->setEnvironmentFilePath(
                $app, $app->environmentFile().'.'.$input->getParameterOption('--env')
            )) {
                return;
            }
        }

        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 bool
     */
    protected function setEnvironmentFilePath($app, $file)
    {
        if (file_exists($app->environmentPath().'/'.$file)) {
            $app->loadEnvironmentFrom($file);

            return true;
        }

        return false;
    }
}

読み取る構成ファイルのパスを決定した後、次のステップは、Configured をロードすることです。

protected function checkForSpecificEnvironmentFile($app)
{
    if ($app->runningInConsole() && ($input = new ArgvInput)->hasParameterOption('--env')) {
        if ($this->setEnvironmentFilePath(
            $app, $app->environmentFile().'.'.$input->getParameterOption('--env')
        )) {
            return;
        }
    }

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

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

namespace Illuminate\Foundation;
class Application ....
{

    public function environmentPath()
    {
        return $this->environmentPath ?: $this->basePath;
    }
    
    public function environmentFile()
    {
        return $this->environmentFile ?: '.env';
    }
}

Laravel は PHP バージョンの Dotenv vlucas/phpdotenv

(new Dotenv($app->environmentPath(), $app->environmentFile()))->load();

/Dotenv/Loader に依存してデータを読み込みます:

class Dotenv
{
    public function __construct($path, $file = '.env')
    {
        $this->filePath = $this->getFilePath($path, $file);
        $this->loader = new Loader($this->filePath, true);
    }

    public function load()
    {
        return $this->loadData();
    }

    protected function loadData($overload = false)
    {
        $this->loader = new Loader($this->filePath, !$overload);

        return $this->loader->load();
    }
}

Loader が設定を読み取るとき、readLinesFromFile関数は、file 関数を使用してファイルから配列に構成を 1 行ずつ読み取り、# で始まるコメントを除外し、内容に = を含む行に対して setEnvironmentVariable メソッドを呼び出して、ファイル行に環境変数を構成します。 :

class Loader
{
    public function load()
    {
        $this->ensureFileIsReadable();

        $filePath = $this->filePath;
        $lines = $this->readLinesFromFile($filePath);
        foreach ($lines as $line) {
            if (!$this->isComment($line) && $this->looksLikeSetter($line)) {
                $this->setEnvironmentVariable($line);
            }
        }

        return $lines;
    }
}

Dotenv が Loader をインスタンス化するとき、Loader が変数を設定するときに、変数値が getEnvironmentVariable を通じて読み取られる場合は、Loader オブジェクトの $immutable プロパティを false に設定します。メソッドを使用すると、この環境変数の設定がスキップされます。したがって、Dotenv はデフォルトでは既存の環境変数を上書きしません。これは非常に重要です。たとえば、docker コンテナー オーケストレーション ファイルでは、PHP アプリケーション コンテナーの Mysql コンテナーに 2 つの環境変数を設定します。 <pre class="brush:php;toolbar:false">namespace Dotenv; class Loader {     public function setEnvironmentVariable($name, $value = null)     {         list($name, $value) = $this-&gt;normaliseEnvironmentVariable($name, $value);         $this-&gt;variableNames[] = $name;         // Don't overwrite existing environment variables if we're immutable         // Ruby's dotenv does this with `ENV[key] ||= value`.         if ($this-&gt;immutable &amp;&amp; $this-&gt;getEnvironmentVariable($name) !== null) {             return;         }         // If PHP is running as an Apache module and an existing         // Apache environment variable exists, overwrite it         if (function_exists('apache_getenv') &amp;&amp; function_exists('apache_setenv') &amp;&amp; apache_getenv($name)) {             apache_setenv($name, $value);         }         if (function_exists('putenv')) {             putenv(&quot;$name=$value&quot;);         }         $_ENV[$name] = $value;         $_SERVER[$name] = $value;     }          public function getEnvironmentVariable($name)     {         switch (true) {             case array_key_exists($name, $_ENV):                 return $_ENV[$name];             case array_key_exists($name, $_SERVER):                 return $_SERVER[$name];             default:                 $value = getenv($name);                 return $value === false ? null : $value; // switch getenv default to null         }     } }</pre> <span style="font-family: 微软雅黑, Microsoft YaHei;">コンテナに環境変数を設定した後、env ファイル内の DB_HOST がホームステッドであり、env 関数を使用して読み取られた場合でも、以前にコンテナに設定されていた DB_HOST 環境変数の値がそのまま残ります。データベース (docker では、コンテナー リンクはデフォルトでサービス名を使用します。オーケストレーション ファイルでは、mysql コンテナーのサービス名をデータベースに設定したため、php コンテナーはデータベース ホストを介して mysql コンテナーに接続する必要があります)。継続的インテグレーションで自動テストを行う場合、通常はコンテナ内でテストするため、Dotenv が既存の環境変数を上書きしないことが非常に重要です。これにより、コンテナ内の環境変数の値を設定するだけでテストを完了できます。プロジェクト内の env ファイルを変更する必要はなく、テストの完了後にプロジェクトを環境に直接デプロイするだけです。 </span><br>環境変数がチェックされても存在しない場合、Dotenv は PHP 組み込み関数 putenv を通じて環境変数を環境に設定し、それを 2 つのグローバル変数 $_ENV と $_SERVER にも保存します。 。

プロジェクトで環境設定を読み取る

Laravel アプリケーションでは、env() 関数を使用して、環境変数の値を読み取ることができます。データベースのホスト:

    environment:
      - "DB_PORT=3306"
      - "DB_HOST=database"
env 関数に渡される 2 番目の値は「デフォルト値」です。指定されたキーに環境変数が存在しない場合は、この値が使用されます。 env 関数のソース コードを見てみましょう:

env('DB_HOST`, 'localhost');
この関数は、PHP 組み込み関数 getenv を通じて環境変数を直接読み取ります。

設定の読み込み時と設定の読み取り時に、putenv と getenv という 2 つの関数が使用されることがわかりました。 putenv によって設定された環境変数はリクエスト中のみ存続し、リクエストの終了後に環境の以前の設定が復元されます。 php.ini の variables_order 構成項目が GPCS になり、E が含まれない場合、PHP プログラムの $_ENV を介して環境変数を読み取ることができないため、開発者が環境変数を動的に設定するために putenv が使用されます。サーバー構成に注意してください。さらに、サーバー上で実行中のユーザーに対して設定された環境変数は、ユーザーが開始したすべてのプロセスで共有されます。これでは、DB_PASSWORD や API_KEY などのプライベート環境変数を十分に保護できません。そのため、この設定は putenv 設定を使用してより適切に保護できます。これらの構成情報を取得すると、getenv メソッドはシステムの環境変数と putenv によって動的に設定される環境変数を取得できます。

以上がLaravel フレームワークでの ENV の読み込みと読み込みの概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。