以下のようなクラスがあるとき。
class Hoo {
public static $value = "Hello world!\n";
}
スタティックなメンバー$valueの値をクラス外から参照したいときには、以下のようにしますよね。
// リテラル文字列でクラスを指定して静的変数を参照
echo "refer to static member by literal name \n";
echo Hoo::$value;
実行結果は当然のごとく
refer to static member by literal name
Hello world!
しかし、このクラスを指定する際に、クラス名が変数に入っていても大丈夫だと言うのです。
そんなことがありうるのでしょうか!
リフレクションなどではなく、名前が文字列で入っているだけなのに!
// クラス名を変数に代入し、クラス名から静的変数を指定
echo "refer to static member by name in variable \n";
$class_name = 'Hoo';
echo $class_name::$value;
実行結果はこちら。
refer to static member by name in variable
Hello world!
できました。
できるのです。
便利だ。便利なのか。
いやどうだろう。
しかしこれだけ見ても、いやー便利だなーとは全然ならないわけで。
クラス名を変数に入れていてそこから静的メンバーを参照したり呼び出したりするメリットはどこにあるでしょうか。
インスタンス化するよりもメモリや実行速度のコストは良さそうな気がします。
でも、その変数がクラス名が入った文字列変数なのか、クラスオブジェクトが入っているインスタンス変数なのかを迷うぐらいであれば、インスタンス化で候補を統一して選挙を戦った方が圧倒的に有利で当選確実な気がします。
何かのフレームワークなどで巨大なクラスが複雑に絡み合うような時には何か活躍の場が見出せるのかもしれません。
ちなみにあんまり関係ありませんが、最初の頃はクラスメンバーを変更できなくしようとして、
class Hoo {
public static final $value = "Hello world!\n"; //miss
}
としてしまい、何がダメかをサクっと検索してみてgoogleの検索結果一覧だけを見て
class Hoo {
final public static $value = "Hello world!\n"; //miss
}
とやって、またダメだったのはがっくりきました。
phpの final は、「このメソッドはオーバーライドできませんよ」という意味だったのです。
しかも、変数には使えないのです。
上記の間違ったコードでの意図は、「変更できないスタティックなメンバー変数」だったのですが、それを満たしてくれるphpのキーワードにはまだ出会っていません。