今回は、「DB接続情報のハードコードを解消し、環境変数(.env)から安全に取得するように修正したリファクタリング」について解説します。
1. 修正前の状態と課題
これまでのレガシーなサンプルコードでは、データベースの接続情報(ホスト名、ユーザー名、パスワードなど)が設定ファイルに直接ハードコードされていました。
修正前 (config.php):
<?php $CONFIG['dsn'] = 'mysql:dbname=smartybook;host=db'; $CONFIG['db_user'] = 'user'; $CONFIG['db_password'] = 'password';
課題
- セキュリティ上のリスク: パスワードなどの機密情報がそのままソースコードに含まれており、誤ってGitリポジトリにプッシュしてしまうと情報漏洩につながる。
- 環境ごとの切り替えの難しさ: ローカル開発環境、ステージング環境、本番環境などで接続情報を変えるたびにコードや設定ファイルを書き換える必要があり、ヒューマンエラーの元になる。
2. 修正内容:環境変数(.env)と Dotenv の導入
モダンなPHPアプリケーションの標準的な手法に倣い、設定をコードから切り離して環境変数(.env)で管理するように改修しました。
実装したファイルの構成
1. .gitignore
機密情報を含む .env ファイルがバージョン管理に誤って含まれないように除外します。
# 2. 設定ファイル
/.env
Code language: PHP (php)
2. .env (ローカル環境用の実ファイル)
DB_HOST=db DB_ROOT_PASSWORD=password DB_DATABASE=smartybook DB_USER=user DB_PASSWORD=password
3. .env.example (リポジトリに含めるひな形)
新しい開発者が環境を構築する際のテンプレートとして用意します。
DB_HOST=db DB_ROOT_PASSWORD=password DB_DATABASE=smartybook DB_USER=user DB_PASSWORD=password
4. bootstrap/app.php (環境変数の読み込み)
Vlucas/phpdotenv などを利用して、プロジェクトルートの .env ファイルを読み込みます。
// .env 読み込み
if (file_exists(PROJECT_ROOT . '/.env')) {
$dotenv = Dotenv::createImmutable(PROJECT_ROOT);
$dotenv->load();
}
5. config.php (環境変数の安全な取得と設定)
カスタムの envString 関数を定義し、型と安全性を担保しながら値を取得します。
<?php
declare(strict_types=1);
/**
* 環境変数を文字列として安全に取得する
*/
function envString(string $key, string $defaultValue = ''): string
{
$val = $_ENV[$key] ?? getenv($key);
if (is_string($val) && $val !== '') {
return $val;
}
return $defaultValue;
}
// $_ENV または getenv から安全に取得(型を string に確定させる)
$dbHost = envString('DB_HOST');
$dbDatabase = envString('DB_DATABASE');
$dbUser = envString('DB_USER');
$dbPassword = envString('DB_PASSWORD');
// PDO設定
$CONFIG['dsn'] = sprintf('mysql:dbname=%s;host=%s', $dbDatabase, $dbHost);
$CONFIG['db_user'] = $dbUser;
$CONFIG['db_password'] = $dbPassword;
💡 さらなる改善に向けたヒント: 現状の
config.phpでは説明変数($dbHostや$dbDatabaseなど)がグローバル空間を汚染しています。これらを無くす、あるいはconfig.php自体を配列としてリターンする構造にすると、よりモダンでクリーンになります。
3. このリファクタリングによる4つのメリット
この変更により、セキュリティ、保守性、運用面において非常に重要なメリットがもたらされます。
1. セキュリティの向上(シークレット情報の保護)
- 機密情報のハードコード排除: パスワードなどの機密情報をソースコードに直接書き込まないことは、セキュリティの基本原則です。
- 情報漏洩リスクの低減:
.envファイルを.gitignoreで除外することで、Gitなどのバージョン管理システムに誤ってシークレットをコミットしてしまうリスクを防ぎます。
2. 環境ごとの設定の分離(柔軟性)
- 環境変化への容易な適応: ローカル開発環境、ステージング環境、本番環境など、環境ごとに異なるDBホスト名やパスワードを、
.envファイルを書き換える(あるいは環境ごとに用意する)だけで切り替えられます。コード変更が不要なため、デプロイプロセスがシンプルかつ安全になります。 - CI/CDパイプラインとの連携: GitHub Actions などの CI/CD ツールを活用し、シークレットとして登録した環境変数をデプロイワークフロー内で動的に
.envファイルに書き出すことで、自動化されたセキュアな環境変数管理が実現できます。
3. 型の安全性と堅牢性の向上
envString関数による安全な取得: 自作のヘルパー関数を挟むことで、値が未設定の場合のデフォルト値を安全に定義できます。- 予期せぬエラーの防止:
$_ENVとgetenvの両方をフォールバックとして考慮し、文字列であることを保証することで、型違いによるトラブルを防ぎます。
4. メンテナンス性の向上
- 保守・管理の効率化: 設定項目が環境変数側に集約されるため、接続先の変更やメンテナンスが必要になった際の見通しが良くなります。
4. 「The Twelve-Factor App」の原則に基づくアプリケーション設計
今回行ったリファクタリングは、モダンなアプリケーション開発のバイブルである 「The Twelve-Factor App(12の要素)」 の原則のうち、「3. Config(設定):環境変数を介して設定をコードから完全に分離する」 に準拠したものです。
レガシーなシステムであっても、こうしたモダンなプラクティスを少しずつ取り入れていくことで、安全でメンテナンスしやすいコードベースに生まれ変わらせることができます。
関連PR

