Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

phpdotenvについて。

More than 1 year has passed since last update.

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)でも推奨されています。

参考:Twelve-Factor Appを噛み砕いてみた

.envファイルは基本的に、.htaccessファイルや Apache や Nginx のバーチャルホストを変更せずに、アプリケーションに必要なカスタム構成変数を簡単に読み込む事ができます。
プロジェクトの外部でファイルを編集する必要がありません。
プロジェクトの実行方法(Apache、Nginx、CLI、PHP 5.4のビルトインWebサーバーなど)に関係なく、すべての環境変数を共有できます。
環境変数を設定することは、他のどんな方法を採用するよりもずっと簡単だと思われます!

  • ApacheやNginxでのバーチャルホストの編集が不要です。
  • php_valueフラグを.htaccessファイルに追加しません。
  • 移植や、必要なENV値の共有が簡単に出来ます。
  • PHPのビルトインWebサーバーやCLIランナーと互換性があります。

インストール方法

Composerを使用します。

shell
composer require vlucas/phpdotenv

参考:【PHP】Composerは絶対必要!インストール方法と解説で完全攻略

使い方

.envファイルには機密情報を含めるため、特別な理由がなければ、
プロジェクトの.gitignoreファイルに.envファイルを追加して
Gitなどのバージョン管理システムで間違ってコミットされる事がないようにしてください。

機密情報ではない環境変数は、一旦.env.exampleという拡張子のファイルを作成して、そこに定義してください。
.envファイルが必要になる人は、各自ローカル環境に.env.exampleファイルをコピーして、
ファイル名を.envに変更してください。
そして、ファイル内で定義してある設定が、ローカル環境で開発をする際に適切な値であることを確認し、
適切じゃない場合は必要に応じて値を変更したり、独自の値を定義したりしてください。

上記の方法をとることで、機密情報がバージョン管理履歴に含まれなくなります。
セキュリティを侵害されるリスクが減り、他のプロジェクトメンバーに機密情報を公開する必要がなくなります。


プロジェクトのrootディレクトリにある.envファイルに、アプリケーションの構成情報を追加しましょう。

.env
S3_BUCKET="dotenv"
SECRET_KEY="souper_seekret_key"

構成情報を他のメンバーに流用されないよう、.envファイルが.gitignoreファイルに追加されていることを確認してください。

.env.exampleと名付けたファイルを作成し、プロジェクトにプッシュします。
このファイルで環境変数を定義しますが、機密情報を公開しないために、値は空白にするか、ダミーの値を入力してください。
変数名は、何についての値なのかが分かるような名前にしましょう。

.env
S3_BUCKET="devbucket"
SECRET_KEY="abc123"

開発中のアプリケーションに.envファイルを読み込みます。

PHP
$dotenv = Dotenv\Dotenv::create(__DIR__);
$dotenv->load();

.env以外のファイル名を使用する場合は、第二引数でファイル名を指定してください。

PHP
$dotenv = Dotenv\Dotenv::create(__DIR__, 'myconfig');
$dotenv->load();

これで、定義されたすべての変数にgetenv()メソッドを使ってアクセスできるようになり、
$_ENV$ _SERVERというスーパーグローバル変数の使用が可能になりました。

参考:PHPのスーパーグローバル変数を使う方法【初心者向け】

PHP
$s3_bucket = getenv('S3_BUCKET');
$s3_bucket = $_ENV['S3_BUCKET'];
$s3_bucket = $_SERVER['S3_BUCKET'];

開発中のアプリケーションに、Laravelなどのフレームワークを使用している場合は、そのフレームワークに存在するRequestクラスを使うこともできます。

PHP
$s3_bucket = $request->env('S3_BUCKET');
$s3_bucket = $request->getEnv('S3_BUCKET');
$s3_bucket = $request->server->get('S3_BUCKET');
$s3_bucket = env('S3_BUCKET');

変数を入れ子にする

環境変数を定義する際、${…}という形式で囲うことで定義済の環境変数を引用できます。
これにより、無意味な作業の繰り返しを減らすことができます。

.env
BASE_DIR="/var/webroot/project-root"
CACHE_DIR="${BASE_DIR}/cache"
TMP_DIR="${BASE_DIR}/tmp"

不変性

デフォルトの挙動では、PHP dotenvが既存の環境変数を上書きすることはありません。
もし既存の環境変数を上書きしたい場合は、load()メソッドではなくoverload()メソッドを使って下さい。

PHP
$dotenv = Dotenv\Dotenv::create(__DIR__);
$dotenv->overload();

Loaderインスタンスのカスタマイズ

$_ENV$_SERVERの変数を使いたくない状況にも、対応可能です!
Dotenv\Environment\FactoryInterfaceのカスタム実装を作成する時にDotenv\Loaderに渡すだけです。

それ以前に、デフォルトの実装では、
基礎となる呼び出しをプロキシするための
Dotenv\Environment\Adapter\AdapterInterface
の配列を提供できるため、カスタム実装さえ必要ない場合もあります。

たとえば、$_ENVputenvだけをいじる場合は、次のようにPHP dotenvをセットアップできます。

PHP
$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ファイル内の変数の存在チェックはされません。

参考: PHPで例外処理を使う方法を現役エンジニアが解説【初心者向け】

これがなければアプリが機能しない、という必須の変数を明示したいときに便利です。

下記の特定の文字列を使用します。

PHP
$dotenv->required('DATABASE_DSN');

複数指定する場合は、配列を使用します。

PHP
$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

空の判定

単に環境変数が定義されているかどうかをチェックするだけではなく、
代入された値が空じゃないかどうかチェックしたい場合は、次のように記入します。

PHP
$dotenv->required('DATABASE_DSN')->notEmpty();

すると、環境変数の値が空だった場合に次のような例外が発生します。

One or more environment variables failed assertions: DATABASE_DSN is empty

整数判定

環境変数に代入された値が整数かどうかチェックしたい場合は、次のように記入します。

PHP
$dotenv->required('FOO')->isInteger();

整数ではなかった場合、次のような例外が発生します。

One or more environment variables failed assertions: FOO is not an integer

真偽値判定

環境変数に代入された値が真偽値かどうかチェックしたい場合は、次のように記入します。
(真偽値以外にも"On","Off","Yes","No","1","0"の値も許容します。)

PHP
$dotenv->required('FOO')->isBoolean();

真偽値ではなかった場合、次のような例外が発生します。

One or more environment variables failed assertions: FOO is not a boolean

特定の値を指定する

環境変数の値に、任意の固定値を指定することもできます。
使用されるであろうオプションやドライバが多くない場合に役立ちます。

PHP
$dotenv->required('SESSION_STORE')->allowedValues(['Filesystem', 'Memcached']);

指定された値に該当しない場合、次のような例外が発生します。

One or more environment variables failed assertions: SESSION_STORE is not an
allowed value

任意の固定値には、正規表現を使用することもできます。

参考: 【5分でまるっと理解】PHP正規表現の使い方まとめ

PHP
$dotenv->required('FOO')->allowedRegexValues('([[:lower:]]{3})');

コメントアウト

.envファイル内では、#を使用してコメントアウトをする事ができます。

.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ライセンス

H40831
Webエンジニアの赤ちゃんです/ 駆け出しエンジニア3年生/ ママはJavaScript/ すっかり仲良しPHP,Vue.js/ Laravelがんばります/ 気になるアイツはSvelte, Flutter, Lightsail… / 現在は自社サービスの開発・運用してます!
mynavicorp
「わたし」の日常に、当たり前にある存在へ ... 総合情報サービス企業
https://www.mynavi.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away