FuelPHPでのConfigの挙動ではまった
2013年08月13日 16時28分
久々FuelPHPネタ。
今回、はまったのはConfigクラス。
なーにも考えずにDBの設定読み込みたいなと思った時に以下のように書きました。
1 2 3 4 5 |
// db.config の読み込み Config::load('db'); // 接続設定 確認 Config::get('default'); |
ここまでの挙動は問題なかったんですがこれやるとフレームワーク側の動きが正常に動かなくなります。
上のケースだとModel::find()とかでエラーが発生するようになります。
こんな感じのエラーです。
Error!
Fuel\Core\FuelException [ Error ]: Database type not defined in configuration
1 2 3 4 5 6 7 8 9 10 |
$config = \Config::get("db.{$name}"); 55 } 56 57 if ( ! isset($config['type'])) 58 { 59 throw new \FuelException("Database type not defined in {$name} configuration"); 60 } 61 62 // Set the driver class name 63 $driver = '\\Database_' . ucfirst($config['type']) . '_Connection'; |
ググってみると「これは正しくdb.configが設定できてないよ」ってページが出てきます。
ですが一部でしか発症しない今回のケースは当てはまりません。
configが正しく読み込めないってことだけは分かったのでConfig::loadを調べてみます。
本家
http://fuelphp.com/docs/classes/config.html#/method_load
日本語(有志の方々に感謝)
http://fuelphp.jp/docs/1.6/classes/config.html#/method_load
第2引数のgroupがデフォルトのnullの場合、rootにマージされるようです。
それを踏まえたうえでエラーが発生した辺りのcore/classes/database/connection.php を覗いてみると以下のように記述されています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public static function instance($name = null, array $config = null) { \Config::load('db', true); if ($name === null) { // Use the default instance name $name = \Config::get('db.active'); } if ( ! isset(static::$instances[$name])) { if ($config === null) { // Load the configuration for this database $config = \Config::get("db.{$name}"); } if ( ! isset($config['type'])) { // ★★★ここの例外がThrowされてる★★★ throw new \FuelException("Database type not defined in {$name} configuration"); } |
$configが取れてないようです。
試しに以下のようなテストを書いてみました。
1 2 3 4 5 6 7 |
// ルートに読み込み Config::load('db'); var_dump(Config::get('default')); // array {...} 読み込める // db.xxxx に読み込み Config::load('db.default', true); var_dump(Config::get('db.default')); // null. 読み込みできてない |
結論
ということで一度Config::load(‘db’)すると再度Config::load(‘db’, true)しても既に読み込み済みという判断になり、Config::get(‘db.xxxxx’)というグループ化した読み込みが出来ないのが原因でした。
Configクラスのファイル既読判定にグループが含まれていないので今回の現象が発生します。
第3引数のreloadをtrueにすると再読み込みされますが、今回はフレームワーク側で発生しているのでこの回避方法は使えませんね。
知らないとはまりそうな挙動でした。