PHPで変数をグローバルに Set/Get したいときに個人的に使っている関数。
function vars($keys = null, $value = null)
{
static $values = array(), $buffer = array();
if (empty($keys)) {
return $values;
} elseif (is_string($keys)) {
if (null !== $value) {
if (false !== strpos($keys, '.')) {
$ex = explode('.', $keys);
$last = count($ex) - 1;
$current = current($ex);
$before = $after = null;
foreach ($ex as $i => $key) {
if ($i !== $last) {
$before .= '{"'.$key.'":';
$after .= '}';
} else {
$before .= '{"'.$key.'":'.json_encode($value);
$after .= '}';
}
}
$data = json_decode($before.$after, true);
$values[$current] = array_replace_recursive(
$values[$current],
$data[$current]
);
return $buffer[$keys] = $value;
} else {
$values[$keys] = $value;
return $value;
}
} elseif (!empty($values[$keys])) {
return $values[$keys];
} elseif (!empty($buffer[$keys])) {
return $buffer[$keys];
} else {
$value = $values;
foreach (explode('.', $keys) as $key) {
if (!array_key_exists($key, $value)) {
return null;
}
$value = $value[$key];
}
return $buffer[$keys] = $value;
}
}
}
第一引数がキー、第二引数が値で、値がある場合はSet、値がない場合はGetになる。
基本的な使い方としては以下のような感じ。
// キーを「A」、値を「B」とした変数のセット
vars('A', 'B');
// キー「A」を取得
echo vars('A'); // -> "B"
// 「A」を上書き
vars('A', 'アタイはAの値');
// 再びキー「A」を取得
echo vars('A'); // -> "アタイはAの値"
// もちろん多次元配列などもセット可能
$value = array(
'C1' => 'ぼくはC1の値',
'C2' => array(
'C2-1' => '俺はC2-1の値',
'C2-2' => 'オラ、C2-2の値',
'C2-3' => '我はC2-3の値',
)
);
vars('C', $value);
// 引数なしの場合は、これまでセットした全部を取得
$all = vars();
/*
array(
'A' => 'アタイはAの値',
'C' => array(
'C1' => 'ぼくはC1の値',
'C2' => array(
'C2-1' => '俺はC2-1の値',
'C2-2' => 'オラ、C2-2の値',
'C2-3' => '我はC2-3の値'
)
)
)
*/
// 存在しないキーの場合は NULL が返る
var_dump(vars('who')); // -> NULL
多次元配列の場合、下層の値へはドットつなぎの文字列でアクセス可。
// 上の例でセットした「C2-2」の値を取得
echo vars('C.C2.C2-2'); // -> "オラ、C2-2の値"
下層の配列の一部を上書きしたい場合もドットつなぎで。
// 上の例でセットした「C2-2」の値を再セット
vars('C.C2.C2-2', '小生がC2-2を上書き');
echo vars('C.C2.C2-2'); // -> "小生がC2-2を上書き"
// この時、「C」の配列は以下のようになっている
array(
'C1' => 'ぼくはC1の値',
'C2' => array(
'C2-1' => '俺はC2-1の値',
'C2-2' => '小生がC2-2を上書き', // ここだけ上書き済み
'C2-3' => '我はC2-3の値',
)
)
ドットつなぎでの取得は static
変数でプチキャッシュしてるので2回目以降は速いはず。
それと、関数内で array_replace_recursive
という関数を使っていて、これは PHP5.3 からの機能なので、それ以下のバージョンの場合は 公式ドキュメントにあるユーザー関数 とかを書いておく必要があるかも。