7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

変数名自体を取得する の理解のためのメモ

Posted at

どれ?

変数名自体を取得する - Qiita
これ。

なに?

すごい、何やってるか全然分からない...

結論

  • 引数の値と$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に先入れ、かどうかは分からないが、先に現れたものがヒットする。


なんとなくやりたくなるときがいまだにまれにある。
今後も忘れた頃にやりたくなって見直すたびに混乱するのもあれなのでメモる。

やりたくなる割になんでやりたかったのかすぐ忘れるたぐいの何か。

7
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?