Javaで言うstatic finalをどうするのが良いか。PHPには定数とオブジェクト定数があって、それぞれdefine関数とconstキーワードで宣言できる。具体的にはこんな感じ。
<?php // 定数 define('MESSAGE', 'Hello World'); echo MESSAGE; // オブジェクト定数 class MyClass { const MESSAGE = 'Hello World'; } echo MyClass::MESSAGE;
オブジェクト定数という名前ではあるけれどもクラス定数と呼んだ方が解り易いかも。constはstaticキーワードなしにstaticな存在になる(staticキーワードを付けるとシンタックスエラー)。
defineとconstの違いは、グローバルなのかクラス帰属なのかと言う点と、宣言時に演算が使えるかという違いがある。例えば、
<?php define('MESSAGE', 100); // OK define('MESSAGE1', 100 + 10); // OK define('MESSAGE2', time()); // OK
このようにdefineだと演算を行ったり関数を呼び出した戻り値を定義することができるが、
<?php class MyClass { const MESSAGE1 = 100; // OK const MESSAGE3 = 100 + 10; // NG const MESSAGE2 = time(); // NG }
constではシンタックスエラーになる。defineではグローバルなので問題にならないけれども、constの場合は継承クラスで値を変更できてしまう(親クラスの値を変更してしまう訳ではないけれど)ので、それを防ぎたい場合であればfinalなclassにする。
<?php final class MyClass { const MESSAGE = 'Hello World'; }
これで子クラスではMESSAGEというメンバーを宣言ができなくなる。ただし、一つのconstに対してのみfinalを付与できないので、クラス単位でfinalになってしまう辺りが不便ではある。
定数ではないけれどもstaticキーワードのついたメンバーだとこんな感じになる。
<?php class MyClass { static $MESSAGE = 'Hello World'; } echo MyClass::$MESSAGE;
変数なので宣言するときも参照するときも$が付く。勿論、値は変更可能。
さて、これらを上手く使うにはどうしたら良いだろう。namespaceが出てくるとこの限りではないけれども、現段階ではグローバルに名前付定数を増やしたくないので、defineの使用はあまりしたくない。そうすると、constを使うことになるけれども、演算して代入ができないので複雑な値を定義できない。つまり、Javaのこういう手段がないみたい。
class MyClass { public static final String MESSAGE; static { MESSAGE = "Hello World"; } }
ということで、文字や数値の場合はconstで良いけれども、計算しないとわからない値や、配列やオブジェクト(これはdefineでも保持できない)はどう扱えうのが上手いのかいまいち解らない。
続きはDoYouPHP?の中の人があとで詳しく書く予定です。ご期待ください。