どれ?
なに?
- 参照渡し
- openssl_random_pseudo_bytes
- 代入
すごい、何やってるか全然分からない...
結論
- 引数の値と
$GLOBALS
の値が同じものの、$GLOBALS
のキーを返して判定している。 - 値で判定しているので、値は引数、
$GLOBALS
ともに一致するユニーク値でなければならない。- なぜなら、同値の別変数がある場合、どちらの変数名を返すか予測が難しいから。誤判定がある。
- そのために参照渡しにして、関数内での引数の書き換えが
$GLOBALS
にも及ぶようにしている。 - 値のユニーク化にopenssl_random_pseudo_bytesを使い、100桁の十分にユニークなランダム文字列を作っている。
-
$GLOBALS
を書き換えているので、もともとの値を保存しておき、最後に戻す処理を加えている。 - こうすることで、関数実行時点で同値を持つ変数がいくらあろうと、判定は100桁のランダム文字列で行われるので誤判定がまず無くなる。
検証
工夫をしない関数を使ってみる
<?php
function get_var_name($var) {
foreach ($GLOBALS as $k => $v) {
if ($v === $var) {
return $k;
}
}
return null;
}
$hoge = 'foo';
var_dump(get_var_name($hoge)); // string(4) "hoge"
いけるじゃんとなるが、
<?php
function get_var_name($var) {
foreach ($GLOBALS as $k => $v) {
if ($v === $var) {
return $k;
}
}
return null;
}
$hoge = 'foo';
$huga = 'foo';
var_dump(get_var_name($hoge)); // string(4) "hoge"
var_dump(get_var_name($huga)); // string(4) "hoge"
ダメになる。
$GLOBALSに先入れ、かどうかは分からないが、先に現れたものがヒットする。
なんとなくやりたくなるときがいまだにまれにある。
今後も忘れた頃にやりたくなって見直すたびに混乱するのもあれなのでメモる。
やりたくなる割になんでやりたかったのかすぐ忘れるたぐいの何か。