-
Notifications
You must be signed in to change notification settings - Fork 0
05 System and Config
Woof の最大の強みである「高いテスタビリティ (テスト容易性)」と「再現性」を支えているのが、システム関数やファイル探索、精度高く設計された内部コンポーネントの徹底的な抽象化です。
この章では、テストを困難にするシステム関数 (時間や乱数) をビジネスロジックから切り離す仕組みと、Woof 内部で利用される設定値 (Config) の網羅について解説します。
PHP の組み込み関数である time() や mt_rand() は非常に便利ですが、ビジネスロジックの中で直接呼び出すと、プログラムが「実行したタイミング」や「運」によって異なる挙動を示すようになります。これは決定論的 (不変) な単体テストを書く上での大きな障害となります。
Woof では、これらを Clock および Random というインターフェースとして完全に抽象化し、 Environment を通じて利用します。
Controller 内で現在時刻が必要な場合は、必ず $env->now() または $env->getClock() を経由して取得します。
// 組み込み関数は使用せず、Environment から現在時刻を取得する
$now = $env->now();
// 1日後のタイムスタンプを計算する場合も、抽象化された時間を起点にする
$tomorrow = $now + 86400;本番環境では実際のシステム時刻を返す DefaultClock が動きますが、単体テスト時には時刻を完全に固定できる FixedClock や、時間を一定量ずらせる ShiftedClock に差し替えることができます。これにより、「特定の有効期限が切れた瞬間のロジック」などのテストを外部ライブラリなしで確実に再現できます。
おみくじやトークン生成などで用いられる整数の乱数も同様に、組み込み関数を使わず $env->rand($min, $max) を経由して取得します。
// 1 から 6 までの乱数を取得する (サイコロの例)
$dice = $env->rand(1, 6);より高度な乱数操作が必要な特殊なケースでのみ $env->getRandom() を呼び出し、 Random オブジェクトを直接操作する想定です。
テスト時には、あらかじめ指定した値の配列を順番に返す ArrayRandom に差し替えることで、本来ランダムであるはずの処理のテストを 100% 決定論的に検証可能になります。
アプリケーションの動作を制御する設定値は、環境 (本番・検証・ローカル開発など) ごとに変化します。これらを安全に管理するのが Config クラスです。
Config は、 WebEnvironmentBuilder で指定された config ディレクトリ内のファイルを自動的にパースし、不変なデータオブジェクトとして保持します。Woof のコアや組み込みの各ファクトリクラスは、この設定ファイルの情報をもとに動作を切り替えます。
内部で参照される標準的な設定キー、およびその内容は以下の通りです。
WebEnvironment が Context オブジェクトを生成する際などに参照される、アプリケーションの全体設定です。
| 設定キー | 内容 | デフォルト値 |
|---|---|---|
app.root-path |
WEBアプリケーションのベースとなるパス。 | / |
app.arg-separator |
URL のクエリパラメータのセパレータ。 | & |
app.locale |
WEBアプリケーションの既定のロケール。設定がない場合はルートロケールに解決します。 | (なし) |
Environment が Logger を構築する際、 StandardLoggerFactory によって参照される設定です。各設定値の詳細な仕様については、 StandardLoggerFactory のクラスコメントにドキュメンテーションされています。
| 設定キー | 内容 | デフォルト値 |
|---|---|---|
logger.dirname |
ログファイルを保存するディレクトリ名。 | logs |
logger.prefix |
ログファイル名のプレフィックス。 | app |
logger.format |
ログ日時の出力フォーマット。 | "Y-m-d H:i:s" |
logger.loglevel |
記録する最小のログレベル。 | info |
logger.multiple |
ログ出力対象の文字列に改行が含まれていた場合、行単位で分割して個別のログとして記録するかどうかのフラグ。有効にするとログの見た目が綺麗に揃います。 | false |
WebEnvironment が SessionStorage を構築する際、 StandardSessionStorageFactory によって参照される設定です。各設定値の詳細な仕様については、 StandardSessionStorageFactory のクラスコメントにドキュメンテーションされています。
| 設定キー | 内容 | デフォルト値 |
|---|---|---|
session.dirname |
セッションデータを保存するディレクトリ名。 | sessions |
session.keyname |
クライアントの Cookie に保存されるセッション ID のキー名。 |
session_name() の戻り値 |
session.max-age |
セッションの有効期限 (秒)。 | php.ini の session.gc_maxlifetime の値 |
session.gc-probability |
古いセッションデータを削除するガベージコレクションの実行確率 (0 以上 1 以下の小数)。 | php.ini の設定に依存 (session.gc_probability / session.gc_divisor) |
WebEnvironment が VariantStorage を構築する際、 StandardVariantStorageFactory によって参照されるキャッシュ制御の設定です。各設定値の詳細な仕様については、 StandardVariantStorageFactory のクラスコメントにドキュメンテーションされています。
| 設定キー | 内容 | デフォルト値 |
|---|---|---|
cache.dirname |
キャッシュデータを保存するディレクトリ名。 | cache |
cache.suffix |
生成されるキャッシュファイルの拡張子 (サフィックス)。 | .dat |
cache.max-age |
キャッシュの有効期限 (秒)。 | 3600 |
cache.gc-probability |
古いキャッシュを削除するガベージコレクションの実行確率 (0 以上 1 以下の小数)。 | 0.01 |
Config クラスでは、ファイル名が「第 1 階層のキー」として扱われます。例えば、 app.common.sitename というキーにアクセスする場合、元の設定ファイルは以下のように定義されます。
JSON 形式の場合 (config/app.json)
{
"common": {
"sitename": "Woof Web"
}
}INI 形式の場合 (config/app.ini) ※セクション名が第 2 階層としてネストされた配列に解釈されます。
[common]
sitename = "Woof Web"設定値を取得する際は、 getString(), getInt(), getBool(), getArray() などのメソッドを使って、目的の型で安全に取り出すことができます。
また、 getInt() などではオプションとして最小値 (min) と最大値 (max) を指定でき、設定ファイルに境界外の異常な値が書かれていた場合でも、強制的にその範囲内に収める (クランプする) ことが可能です。
$config = $env->getConfig();
// 文字列として取得 (見つからない場合のデフォルト値を第2引数で指定)
$sitename = $config->getString("app.common.sitename", "Default Site");
// 整数として取得 (最小値と最大値を指定して安全性を担保)
// 例: 設定値が -5 なら 0 に、150 なら 100 に強制的に補正されます
$limit = $config->getInt("app.pagination.limit", 20, 0, 100);
// 真偽値として取得
$debugMode = $config->getBool("app.debug", false);