PHPで環境変数を使用する方法

October 14, 2021
執筆者
レビュー担当者

この記事はMatthew Setterこちらで公開した記事(英語)を日本語化したものです。

環境変数は、PHPアプリケーションを構築する上で非常に便利なツールです。環境変数を使えば、アプリケーションの設定をコード外に保管できます。コード外に保管することで、認証情報の漏洩を防いだり、 アプリケーションを効率的にメンテナンスしたり、複数の環境にわたってアプリケーションを使用することが容易になります。

本稿では、PHPアプリケーションでの環境変数の設定や取得をするための方法をご紹介します。アプリケーションでAPIキー、アップロードされたファイル、クエリ文字列、フォームデータなどの情報を環境変数としてアクセスできるようになります。

PHPで環境変数にアクセスする方法

PHPのスーパーグローバル変数を使用する

PHPで環境変数にアクセスする最も一般的な方法のひとつが、スーパーグローバル変数を使用することです。スーパーグローバル変数は組み込みの定義済み変数で、すべてのスコープで利用可能です。PHPランタイムによって初期化され、PHPの環境情報を論理的かつ効率的に整理し、必要な情報を取得するためにひとつの配列を参照するだけでよいようにします。

例えば、$_SERVERにはリクエストヘッダー、パス、スクリプトの場所が含まれ、 $_SESSIONにはセッション変数が含まれます。また、$_POSTにはHTTP POSTメソッドで呼ばれたときに現在のスクリプトに渡される変数が含まれます。

スーパーグローバル変数の使用にあたって、注意点もあります。

  • まず、variables_orderディレクティブの設定によっては、スーパーグローバル配列の1つまたは複数が空になる場合があります。アプリケーションが特定のスーパーグローバル変数が入力されていることに依存している場合は、この点を確認することが重要です。
  • 2つ目は、スクリプトのコンテキストによって、$_SERVER$_ENV(PHPパーサーが動作している環境からインポートした変数を含む)に含まれる変数が重複することがあります。すべてのスーパーグローバル変数でキーが一意であることを期待していた場合、混乱するかもしれません。

SAPI/CGI、CLI環境の違いについて

スーパーグローバル変数にどのような情報を設定するかは、variables_order ディレクティブだけでなく、環境も関係します。具体的には、アプリケーションが CGIFastCGI SAPIで動作している場合、通常の変数に加え、環境変数が設定されます。または、PHP CLIを使用している場合は、$_SERVERのみが設定されます。

getenv()を使用する

PHPのスーパーグローバル変数を使用する以外に、getenv()を使用して環境変数を取得できます。 この関数が引数なしで呼ばれた場合、利用可能なすべての環境変数が返されます。しかし、引数が渡された場合は、その名前の環境変数の値が返されます。

使用例は、以下のとおりです。

echo getenv('SHELL');
foreach (getenv() as $key => $value) {
    echo $key . ' - ' . $value;
}

PHPのスーパーグローバル変数と同様、この関数を使用する際にも注意点があります。この関数に関するドキュメントを以下に引用します。

PHPがFast CGIのようなSAPIで動作している場合、putenv()で同名のローカル環境変数を設定しても、この関数は常にSAPIで設定された環境変数の値を返します。ローカルに設定された環境変数の値を返したい場合は、local_onlyパラメータを使用します。

(英語のドキュメントをTwilioにより日本語に翻訳)

getenv()はスレッドセーフではありません。

apache_getenv()を使用する

もし、WebサーバーとしてApacheを使用しているのであれば、apache_getenv()が使えます。この関数は、Apacheのプロセスで設定されている環境変数を取得します。以下に使用例を示します。

echo apache_getenv('NAME');

環境変数も検証が必要

PHPのスーパーグローバル変数やWebサーバーの設定、動作環境など、データの出所がどこであろうと、完全に信用できるわけではありません。環境変数は、アプリケーションの外部にある他のデータと同じように フィルタリングや検証を行う必要があります。

環境変数の設定方法

環境変数を読むだけでなく、その設定方法を知っておくと、必要なときに環境変数を変更することができます。次の例では、環境変数、NAMEに、イギリスのロックバンド The Cureのリードボーカルである 「Robert Smith」を設定しています。

環境に設定する

Webサーバーを起動したり、PHPスクリプトを実行したりする前に、現在の環境に環境変数を設定することができます。

環境変数の設定についてより深く学びたい方は、Twilioブログの「環境変数の設定方法」を参照してください。

UNIX、Linux、macOS

これら3つのオペレーティングシステム、またはBSDのような亜種を使用している場合、環境変数を設定できるスコープが3つあります。

  • 現在の環境(セッション)およびすべての子セッションで利用可能
  • 現在のセッションでのみ利用可能
  • 特定のプロセスでのみ利用可能

以下のコードで、この3つの例を見ることができます。

# 現在の環境(セッション)およびすべての子セッションで利用可能
export NAME="Robert Smith"

# 現在のセッションでのみ利用可能
NAME="Robert Smith"

# 特定のプロセスでのみ利用可能。
NAME="Robert Smith" php script.php

Microsoft Windows

Microsoft Windowsでは、環境変数の設定方法が少し異なります。コントロールパネルから設定するか、コマンドプロンプトやPowerShellコンソールで設定できます。以下に後者2つの例を示します。

# WindowsのコマンドプロンプトでNAMEを設定する
set NAME="Robert Smith"

# Windows PowerShellのコンソールでNAMEを設定する
$Env:NAME = "Robert Smith"

Dockerを使用する

Dockerを使用している場合、以下の例のようにENVコマンドを使ってDockerfilesに環境変数を設定することができます。

ENV NAME "Robert Smith"

Docker Composeを使ってマルチコンテナ構成を構築する場合、以下の例のようにdocker-compose.ymlで環境変数を環境キーで設定することが可能です。

environment:
  - NAME="Robert Smith"

Dockerで作業する際の環境変数の設定方法は他にもいくつかあり、DockerドキュメントDocker Composeドキュメントに記載されています。

putenv()を使用する

この機能を使うと、現在のリクエストの中で環境変数の値を設定したり、設定を解除したりすることができます。次のリクエストでは、もし変数が現在のリクエストの外に設定されていれば、元の値に戻ります。

このようにして設定された変数は、そのスクリプトによって呼び出されたプロセスでも利用可能であり、またgetenv()を呼び出すことによってのみ利用可能です。

以下のコードで、両方の関数の例を見ることができます。

// 環境変数「NAME」を設定する
putenv('NAME="Robert Smith"');

// 環境変数「NAME」を取得する
echo getenv('NAME');

// 環境変数「NAME」の設定を解除する
putenv('NAME');

putenv()はスレッドセーフではありません。

 

apache_setenv()を使用する

putenv()に似ているものに、apache_setenv()があります。この関数は Apacheプロセス固有の環境変数を設定します。当然ながら、この関数とその補集合はApacheを使用しているときのみ利用可能です。以下に使用例を示します。

apache_setenv('NAME', 'Robert Smith');
echo apache_getenv('NAME');

NGINXに環境変数を設定する

NGINXをWebサーバーとして使用している場合、fastcgi_paramディレクティブを使用して環境変数を設定できます。このディレクティブは、大文字と小文字を区別する名前と値を取り、スペースが含まれる場合は引用符で囲む必要があります。

fastcgi_param NAME "Robert Smith";

これらの変数は、getenv() や、スーパーグローバル配列 の中の$_ENVや $_SERVERで利用できます。

Apacheに環境変数を設定する

WebサーバーとしてApacheを使用している場合、環境変数を設定するためにSetEnvディレクティブを使用できます。このディレクティブは、Apacheのメインサーバー設定、バーチャルホスト設定、ディレクトリ設定、または.htaccessファイルで使用できます。

このディレクティブは、大文字小文字を区別する名前と値を取り、空白を含む場合は、引用符で囲む必要があります。値が提供されない場合、変数は空の文字列に初期化されます。

SetEnv NAME "Robert Smith"

NGINXのfastcgi_param と異なり、ApacheのSetEnv(または関連する関数)で設定した環境変数は、$_SERVERスーパーグローバル関数でしか使用できません。

.envファイルの使用

上記の方法にはそれぞれメリットがありますが、留意すべきデメリットもいくつかあります。

  • プロジェクトの複雑さによっては、長期間にわたって維持することが困難な場合もあります。
  • 必要な環境変数をまとめたリスト、与えられた変数が何をするかについての詳細、および許可されたデータ型はありません。

別のアプローチとして、近年PHPで大きな支持を得ているのが、dotenvファイルを使用する方法です。これは、環境変数の保存によく使用される.envにちなんで命名されました。アプリケーションが動作するために必要な環境変数をキー・値 のペアのリストとして定義したプレーンテキストファイルです。

以下に例を示します。

NAME="Robert Smith"

上の例がプロジェクトの .env ファイルだったとすると、vlucas/phpdotenv のようなパッケージを使用すると、デフォルトで.envファイルを読み込み、その中で定義されている変数を$_ENVと $_SERVERスーパーグローバル変数に追加することが可能です。

そのためには、まず、以下のコマンドを実行して、パッケージをアプリケーションの依存関係としてインストールすることになります。

composer require vlucas/phpdotenv

そして、以下の例のように、パッケージを使用して環境変数を読み込みます。

<?php

declare(strict_types=1);

require_once('vendor/autoload.php');

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

echo $_ENV['NAME'] . "\n";
echo $_SERVER['NAME'] . "\n";
  • .envが見つからない場合に例外をスローしないようにするために、load() ではなく、safeLoad()を使用します。
  • .env以外のファイルを使用する場合は、ファイルパスを二つ目の引数に渡します。

.envファイルはバージョン管理下に置いてはいけません。

dotenvファイルに含まれる機密データは、リポジトリにアクセスできる人なら誰でも利用可能になるため、dotenvを使用するセキュリティ上の利点がすべて失われます。そのため、バージョン管理から除外するのが一般的です。例えば、Gitを使用する場合は、プロジェクトの.gitignoreファイルに.env(およびそのファイル名のバリエーション)を追加してください。

PHP で環境変数を使用する方法をご紹介しました

本稿で、PHPプロジェクトで環境変数を使用する方法を理解していただけたのではないでしょうか。PHPで環境変数を扱う方法を他にご存知であれば、ぜひ教えてください!

Matthew Setterは、Twilio VoicesチームのPHP編集者兼ポリグロットの開発者です。彼はDocker EssentialsMezzio Essentialsの著者でもあります。PHPコードの作成に取り組んでいないときは、TwilioのPHP記事の優秀な編集者です。彼の連絡先はmsetter@twilio.comです。また、TwitterGitHubでも情報を発信しています。