phpdotenvについて勉強しようと思ったのですが、全体的な説明をしてくださっている記事が見つからなかったので、自力で公式のREAD ME.mdを日本語に訳しました。
前提知識が必要そうなワードは太字にして、参考になりそうな記事のリンクを追記しています。(PHPの公式マニュアルは日本語の説明文が難解なのでリンクを張っていませんが、適宜そちらも読みながら理解することをオススメします。)
当方、勉強中の者ですので、不適切な表現がある箇所はバシバシご指摘ください!
(特に、Loader Customizationの項がほとんど理解できていないため、ご指摘お待ちしております。)
(2019年10月執筆)
PHP dotenvとは
PHP dotenvは、Ruby言語で使われている**dotenv**のPHP版です。
getenv()
メソッドや、$_ENV
変数、$_SERVER
変数を使って、.env
というファイルから環境変数を読み込むことができます。
参考:環境変数とは
Ver.2からの変更点
Ver.3で実装された新機能について説明します。
-
複数行にわたる変数に対応しました(#301)。
-
環境のどの部分を読み取り及び変更しようとするかの柔軟性が大幅に向上します(#300)。
これにより、必要に応じた正しいカスタマイズが可能になります。 -
新しいネイティブコンストラクターは
Loader
インスタンスを取得するため、今までnew Dotenv(...)
と記入していた箇所をDotenv::create(...)
と書き換える必要があります。) -
Loader
インスタンスは値をトリミングしなくなります(#302)。 -
Loader::load()
とその呼び出し元は、ピュアな配列ではなく、値が読み込まれた変数の連想配列を返すようになります(#306)。
詳細は、リリースノートとアップグレードガイドを参照してください。
なぜ.env
を使うべきなのか?
データベースや外部サービスの、ユーザー名やパスワード、APIキーなどの機密情報をソースコードに記入しないためです。
環境によって変更する可能性のあるものはすべて、ソースコードの外で環境変数として定義するべきです。
この方法は、モダンなWebアプリが守るべき12の要素(原題:Twelve-Factor App)でも推奨されています。
.env
ファイルは基本的に、.htaccess
ファイルや Apache や Nginx のバーチャルホストを変更せずに、アプリケーションに必要なカスタム構成変数を簡単に読み込む事ができます。
プロジェクトの外部でファイルを編集する必要がありません。
プロジェクトの実行方法(Apache、Nginx、CLI、PHP 5.4のビルトインWebサーバーなど)に関係なく、すべての環境変数を共有できます。
環境変数を設定することは、他のどんな方法を採用するよりもずっと簡単だと思われます!
- ApacheやNginxでのバーチャルホストの編集が不要です。
-
php_value
フラグを.htaccess
ファイルに追加しません。 - 移植や、必要なENV値の共有が簡単に出来ます。
- PHPのビルトインWebサーバーやCLIランナーと互換性があります。
インストール方法
Composerを使用します。
composer require vlucas/phpdotenv
使い方
.env
ファイルには機密情報を含めるため、特別な理由がなければ、
プロジェクトの.gitignore
ファイルに.env
ファイルを追加して
Gitなどのバージョン管理システムで間違ってコミットされる事がないようにしてください。
機密情報ではない環境変数は、一旦.env.example
という拡張子のファイルを作成して、そこに定義してください。
.env
ファイルが必要になる人は、各自ローカル環境に.env.example
ファイルをコピーして、
ファイル名を.env
に変更してください。
そして、ファイル内で定義してある設定が、ローカル環境で開発をする際に適切な値であることを確認し、
適切じゃない場合は必要に応じて値を変更したり、独自の値を定義したりしてください。
上記の方法をとることで、機密情報がバージョン管理履歴に含まれなくなります。
セキュリティを侵害されるリスクが減り、他のプロジェクトメンバーに機密情報を公開する必要がなくなります。
プロジェクトのroot
ディレクトリにある.env
ファイルに、アプリケーションの構成情報を追加しましょう。
S3_BUCKET="dotenv"
SECRET_KEY="souper_seekret_key"
構成情報を他のメンバーに流用されないよう、.env
ファイルが.gitignore
ファイルに追加されていることを確認してください。
.env.example
と名付けたファイルを作成し、プロジェクトにプッシュします。
このファイルで環境変数を定義しますが、機密情報を公開しないために、値は空白にするか、ダミーの値を入力してください。
変数名は、何についての値なのかが分かるような名前にしましょう。
S3_BUCKET="devbucket"
SECRET_KEY="abc123"
開発中のアプリケーションに.env
ファイルを読み込みます。
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
.env
以外のファイル名を使用する場合は、第二引数でファイル名を指定してください。
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__, 'myconfig');
$dotenv->load();
これで、定義されたすべての変数にgetenv()
メソッドを使ってアクセスできるようになり、
$_ENV
や$ _SERVER
というスーパーグローバル変数の使用が可能になりました。
$s3_bucket = getenv('S3_BUCKET');
$s3_bucket = $_ENV['S3_BUCKET'];
$s3_bucket = $_SERVER['S3_BUCKET'];
開発中のアプリケーションに、Laravelなどのフレームワークを使用している場合は、そのフレームワークに存在するRequest
クラスを使うこともできます。
$s3_bucket = $request->env('S3_BUCKET');
$s3_bucket = $request->getEnv('S3_BUCKET');
$s3_bucket = $request->server->get('S3_BUCKET');
$s3_bucket = env('S3_BUCKET');
変数を入れ子にする
環境変数を定義する際、${…}
という形式で囲うことで定義済の環境変数を引用できます。
これにより、無意味な作業の繰り返しを減らすことができます。
BASE_DIR="/var/webroot/project-root"
CACHE_DIR="${BASE_DIR}/cache"
TMP_DIR="${BASE_DIR}/tmp"
不変性
デフォルトの挙動では、PHP dotenvが既存の環境変数を上書きすることはありません。
もし既存の環境変数を上書きしたい場合は、load()
メソッドではなくoverload()
メソッドを使って下さい。
$dotenv = Dotenv\Dotenv::create(__DIR__);
$dotenv->overload();
Loader
インスタンスのカスタマイズ
$_ENV
や$_SERVER
の変数を使いたくない状況にも、対応可能です!
Dotenv\Environment\FactoryInterface
のカスタム実装を作成する時にDotenv\Loader
に渡すだけです。
それ以前に、デフォルトの実装では、
基礎となる呼び出しをプロキシするための
Dotenv\Environment\Adapter\AdapterInterface
の配列を提供できるため、カスタム実装さえ必要ない場合もあります。
たとえば、$_ENV
とputenv
だけをいじる場合は、次のようにPHP dotenvをセットアップできます。
$factory = new Dotenv\Environment\DotenvFactory([
new Dotenv\Environment\Adapter\EnvConstAdapter(),
new Dotenv\Environment\Adapter\PutenvAdapter(),
]);
$dotenv = Dotenv\Dotenv::create(__DIR__, null, $factory);
環境変数の定義を要求する
PHP dotenvを使って、$_ENV
と$_SERVER
の変数、もしくはgetenv()
メソッドに環境変数を定義するよう要求することができます。
(定義されていない場合は、例外をスローします。)
注: .env
ファイル内の変数の存在チェックはされません。
これがなければアプリが機能しない、という必須の変数を明示したいときに便利です。
下記の特定の文字列を使用します。
$dotenv->required('DATABASE_DSN');
複数指定する場合は、配列を使用します。
$dotenv->required(['DB_HOST', 'DB_NAME', 'DB_USER', 'DB_PASS']);
指定した環境変数が定義されていない場合、
PHP dotenvが次のように**定義済みの例外(RuntimeException)**をスローします。
参考: PHPでのエラー処理・例外処理
One or more environment variables failed assertions: DATABASE_DSN is missing
空の判定
単に環境変数が定義されているかどうかをチェックするだけではなく、
代入された値が空じゃないかどうかチェックしたい場合は、次のように記入します。
$dotenv->required('DATABASE_DSN')->notEmpty();
すると、環境変数の値が空だった場合に次のような例外が発生します。
One or more environment variables failed assertions: DATABASE_DSN is empty
整数判定
環境変数に代入された値が整数かどうかチェックしたい場合は、次のように記入します。
$dotenv->required('FOO')->isInteger();
整数ではなかった場合、次のような例外が発生します。
One or more environment variables failed assertions: FOO is not an integer
真偽値判定
環境変数に代入された値が真偽値かどうかチェックしたい場合は、次のように記入します。
(真偽値以外にも"On"
,"Off"
,"Yes"
,"No"
,"1"
,"0"
の値も許容します。)
$dotenv->required('FOO')->isBoolean();
真偽値ではなかった場合、次のような例外が発生します。
One or more environment variables failed assertions: FOO is not a boolean
特定の値を指定する
環境変数の値に、任意の固定値を指定することもできます。
使用されるであろうオプションやドライバが多くない場合に役立ちます。
$dotenv->required('SESSION_STORE')->allowedValues(['Filesystem', 'Memcached']);
指定された値に該当しない場合、次のような例外が発生します。
One or more environment variables failed assertions: SESSION_STORE is not an
allowed value
任意の固定値には、正規表現を使用することもできます。
$dotenv->required('FOO')->allowedRegexValues('([[:lower:]]{3})');
コメントアウト
.env
ファイル内では、#
を使用してコメントアウトをする事ができます。
# this is a comment
VAR="value" # comment
VAR=value # comment
使用上の注意
新規で開発に参画した方があなたのソースコードを使用する場合、
その方は.env.example
ファイルの名前を.env
に変更して、
適切な値を記入する必要があります。
シェルで環境変数を使用する場合
PHP dotenvを使用するのではなく、シェルの中で.env
ファイルの環境変数を使用したい場合は、source
コマンドを使ってください。
source .env
セキュリティについて
もし、PHP dotenvにセキュリティ上の脆弱性を発見した場合は、
開発者の Graham Campbell にメールを送信してください。
MAIL: graham@alt-three.com
すべての脆弱性に迅速に対処します。
弊社のセキュリティポリシーは、こちらでご覧いただけます。
ライセンス
PHP dotenvの権利は、**三条項BSDライセンス**に基づき主張します。
参考:BSDライセンス