2007年5月前後のメモ。Antのプロパティ値とかで "${...}" とかで別のプロパティ値を埋め込めるのが羨ましくて、PHPで何とかできないかなぁ・・・と試してみた時の記事です。
次のようにINIファイル中で、前に出てきたキーの値を埋め込めるようなINIパーサーが欲しい。
[sect1]
a.b.c = hoge
a.b.d = bohe
key0 = Hello, ${key3}!!
key1 = Hello, ${a.b.c}!!
key2 = Hello, everyone, ${a.b.c},${a.b.d}!!
key3 = Hello, ${ab.c}!!
これが、次のようにparseできれば良い。
array {
"a.b.c" => "hoge"
"a.b.d" => "bohe"
"key0" => "Hello, Hello, ${ab.c}!!!!"
"key1" => "Hello, hoge!!"
"key2" => "Hello, everyone, hoge,bohe!!"
"key3" => "Hello, !!"
}
・・・う~~ん・・・上の例の"${ab.c}"のように、未定義の変数表現が出てきたらどうするか。
・・・場合によってはどちらも妥当だろう。この辺は実際にライブラリ側でどうにかすべきだろう。
というわけで、コンセプトコード。正規表現でかなり悩んだけど、それ以外は意外と、すんなり書けてしまった。
<?php
$configs = array(
"a.b.c" => "hoge",
"a.b.d" => "bohe",
'key0' => 'Hello, ${key3}!!',
'key1' => 'Hello, ${a.b.c}!!',
'key2' => 'Hello, everyone, ${a.b.c},${a.b.d}!!',
'key3' => 'Hello, ${ab.c}!!',
);
function test($configs) {
$configs_copy = $configs;
foreach($configs as $k => $v) {
if(!preg_match_all('/\$\{([\w\d\/\.,-_]*)\}/', $v, $matches)) {
continue;
}
$originals = $matches[0];
$keys = $matches[1];
$replacer = array();
foreach($originals as $_index => $_o) {
$_k = $keys[$_index];
if(isset($configs[$_k])) {
$replacer[] = $configs[$_k];
} else {
$replacer[] = "";
}
}
$configs_copy[$k] = str_replace($originals, $replacer, $v);
}
return $configs_copy;
}
var_dump(test($configs));
$configs = array(
'pokox.root_dir' => '/opt/lib/php/pokox',
'pokox.app_dir' => '/var/www/app1',
'pokox.kernel_dir' => '${pokox.root_dir}/kernel',
'pokox.vendor_dir' => '${pokox.root_dir}/vendor',
);
var_dump(test($configs));
?>
→出力:
> php AppConfig_alpha.php
array(6) {
["a.b.c"]=>
string(4) "hoge"
["a.b.d"]=>
string(4) "bohe"
["key0"]=>
string(25) "Hello, Hello, ${ab.c}!!!!"
["key1"]=>
string(13) "Hello, hoge!!"
["key2"]=>
string(28) "Hello, everyone, hoge,bohe!!"
["key3"]=>
string(9) "Hello, !!"
}
array(4) {
["pokox.root_dir"]=>
string(18) "/opt/lib/php/pokox"
["pokox.app_dir"]=>
string(13) "/var/www/app1"
["pokox.kernel_dir"]=>
string(25) "/opt/lib/php/pokox/kernel"
["pokox.vendor_dir"]=>
string(25) "/opt/lib/php/pokox/vendor"
}