【Laravel】.envファイルの設定と管理のベストプラクティス|config()・env()の使い分けと注意点

はじめに

Laravelを使い始めると、.env ファイルと config() 関数の使い分けに迷うことがあります。

「どこで env() を使って、どこで config() を使えばいいのか」「config:cache を実行したら env() が効かなくなった」「.envをGitに含めてしまって大丈夫?」といった疑問や失敗は、実務でよく遭遇します。

この記事では、.env ファイルの基本から env()config() の正しい使い分け、config:cache との関係、Gitでの管理方法、実務でのベストプラクティスまで整理します。

.envファイルの基本

.env はアプリケーションの実行環境に依存する設定値を管理するファイルです。ローカル・ステージング・本番など、環境ごとに異なる値(DBの接続情報、APIキー、メール設定など)を外部化することで、コードを変更せずに動作を切り替えられます。

基本的な書き方

APP_NAME=MyApp
APP_ENV=local
APP_DEBUG=true
APP_URL=http://localhost

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=my_database
DB_USERNAME=root
DB_PASSWORD=secret

MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525

キーはすべて大文字のスネークケースが慣習です。値にスペースが含まれる場合はダブルクォートで囲みます。

APP_NAME="My Laravel App"

.env.example との関係

.env はGitに含めず、.env.example をコミットするのが基本です。

# .gitignore に含まれているか確認
.env

.env.example には実際の値を入れず、キー名と説明だけ書いておきます。

APP_NAME=
APP_ENV=local
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=

新しいメンバーがプロジェクトに参加するときは、.env.example をコピーして .env を作成します。

cp .env.example .env
php artisan key:generate

env()とconfig()の違いと使い分け

env()とは

env().env ファイルの値を直接読み取る関数です。

$debug = env('APP_DEBUG');
$dbHost = env('DB_HOST', '127.0.0.1'); // 第2引数はデフォルト値

config()とは

config()config/ ディレクトリ内の設定ファイルを経由して値を取得します。

$debug = config('app.debug');
$dbHost = config('database.connections.mysql.host');

config/app.php の中では env() を使って .env の値を参照しています。

// config/app.php
return [
    'debug' => env('APP_DEBUG', false),
    'name'  => env('APP_NAME', 'Laravel'),
];

使い分けの原則

アプリケーションコード(コントローラ、サービスクラス、モデルなど)では config() を使い、env()config/ ディレクトリ内だけで使うのが原則です。

// NG:アプリケーションコード内でenv()を直接使う
class PaymentService
{
    public function __construct()
    {
        $this->apiKey = env('STRIPE_SECRET_KEY');
    }
}

// OK:config()経由で取得する
class PaymentService
{
    public function __construct()
    {
        $this->apiKey = config('services.stripe.secret');
    }
}

この原則に従う理由は次のセクションで説明します。

config:cacheとenv()の関係

config:cacheとは

php artisan config:cache は、config/ ディレクトリ内のすべての設定ファイルをひとつにまとめてキャッシュするコマンドです。本番環境でのパフォーマンス向上のために使われます。

php artisan config:cache

config:cache実行後にenv()が効かなくなる理由

config:cache を実行すると、LaravelはキャッシュされたファイルからのみPRO設定を読み込むようになり、.env ファイルを直接読み込まなくなります。

その結果、アプリケーションコード内で env() を直接呼んでいると、キャッシュ後に常に null が返るようになります

// config:cache後にnullが返る(NG)
$key = env('STRIPE_SECRET_KEY'); // → null

// こちらは正常に動作する(OK)
$key = config('services.stripe.secret');

確認・クリア方法

# キャッシュをクリア
php artisan config:clear

# キャッシュ再生成
php artisan config:cache

ローカル開発環境では config:cache は基本的に不要です。本番デプロイ時にのみ実行するのが一般的です。

.envをGitで管理する際の注意点

.envは必ずGitignoreに含める

.env にはDBのパスワード・APIキー・秘密鍵などの機密情報が含まれます。絶対にGitにコミットしてはいけません。

Laravelのデフォルトの .gitignore に含まれているので、通常は問題ありませんが、明示的に確認しておきましょう。

cat .gitignore | grep .env
# .env が含まれているかを確認

誤ってコミットしてしまった場合

もし .env をコミットしてしまった場合は、次の手順で対処します。

# Gitの追跡から除外
git rm --cached .env

# .gitignoreに追加して再コミット
echo ".env" >> .gitignore
git add .gitignore
git commit -m "Remove .env from tracking"

ただし、コミット履歴には残ります。機密情報が含まれていた場合は、**APIキーやパスワードを即座にローテーション(再発行)**することが必要です。GitHubにpushしてしまった場合は特に注意が必要です。

.env.testingと.env.example

ファイルGitに含める用途
.env❌ 含めないローカル環境の設定値
.env.example✅ 含めるキー名のテンプレート
.env.testing❌ 基本含めないテスト実行時の設定値

.env.testing はPHPUnitを実行する際に自動的に読み込まれます。テスト用DBの設定などを分離する場合に使います。

# .env.testing
APP_ENV=testing
DB_DATABASE=my_database_testing

実務でのベストプラクティス

1. 新しい環境変数はconfig/に必ず対応するキーを追加する

.env に新しいキーを追加するときは、必ず対応する config/ ファイルにも追加します。

# .env
EXTERNAL_API_KEY=your_api_key_here
EXTERNAL_API_URL=https://api.example.com
// config/services.php
return [
    'external_api' => [
        'key' => env('EXTERNAL_API_KEY'),
        'url' => env('EXTERNAL_API_URL', '<https://api.example.com>'),
    ],
];
// アプリケーションコード
$apiKey = config('services.external_api.key');

2. .env.exampleを最新に保つ

チーム開発では、.env に新しいキーを追加したら必ず .env.example にも追加します。追加し忘れると、他のメンバーが環境構築時に気づかずバグの原因になります。

# .env に新しいキーを追加した後
vi .env.example  # 値なしでキーを追加
git add .env.example
git commit -m "Add EXTERNAL_API_KEY to .env.example"

3. デフォルト値を適切に設定する

env()config() にはデフォルト値を必ず設定します。.env に値がない場合でもアプリケーションが壊れないようにします。

// config/mail.php
'port' => env('MAIL_PORT', 587),
'encryption' => env('MAIL_ENCRYPTION', 'tls'),

4. APP_ENVで環境を判定する

環境ごとに処理を分岐する場合は app()->environment()config('app.env') を使います。

// OK
if (app()->environment('production')) {
    // 本番のみの処理
}

if (app()->isProduction()) {
    // こちらも可
}

// NG:env()を直接使わない
if (env('APP_ENV') === 'production') {
    // config:cache後に正常動作しない
}

5. 機密情報の管理にはAWS Secrets ManagerやParameter Storeを検討する

本番環境の機密情報(DBパスワード・APIキー)を .env ファイルで管理するのはシンプルですが、セキュリティを高めるために AWS Secrets Manager や Parameter Store を使う方法もあります。

Laravel では vlucas/phpdotenv がベースになっているため、起動時にSecrets Managerから値を取得して $_ENV に注入するアダプターを実装することも可能です。

まとめ

項目ポイント
env() の使いどころconfig/ ディレクトリ内のみ
config() の使いどころアプリケーションコード全般
config:cache の注意実行後は env() が直接使えなくなる
.env のGit管理絶対にコミットしない。誤った場合はキーをローテーション
.env.exampleチームで必ず最新に保つ

env() をアプリケーションコードで直接使うのは、config:cache 実行後のバグの温床になります。env()config/ ファイルの中だけ、という原則を守るだけで多くのトラブルを防げます。

LaravelLaravel,PHP

Posted by 千原 耕司