PHPのtraitを使ったEnumの実装
このエントリはPHP Advent Calendar 2013 – Qiitaの25日目です。
Enumを作りました。GitHubに置いてあります。satooshi/ValueObject。参考にしたのはC#のEnum。未実装の部分もありますが、よく使いそうなメソッドは実装しました。
Enum
名前はValueObjectになってますが、欲しかったのはEnumの方です。こんな風にして使います。例えば性別や既婚・独身みたいなステータス。
Enumというと連番を想像しますが、文字列でも値を定義できます。むしろ連番定数を定義したい、とは思いますが、定数を定義しつつ自動的に定数値を割り当てるには、自動生成するしかない気がします。Settyの方法がおそらくそういうやり方なんじゃないかと。
Flags attribute
Enumの中でも、排他的な値ではなく、同時に複数の値を持てるような場合、.NETではFlagsという属性を付ける事ができます(だったはず)。PHPでもエラーレベルの指定方法で、こういった定数が使用されてますね。
例えば、フォントの指定方法として、
- 下線
- イタリック
- ボールド
などがあったとします。これらはすべて同時に指定可能、あるいは指定なしだったとすると、
こんなクラスを作ることができます。
use case
Symfony2アプリケーションで使う場面はこんな感じ。
- Formのchoiceフィールドとして使う(値と名前の組)
- Twigテンプレートで名前を表示する
- DoctrineでDBに永続化する
Form
getOptions()
で[名前 => 値]の配列が取得できるので、[値 => 名前]にすると、そのままformオプションに使えます。
Twig
個別の列挙値の名前が必要であれば、インスタンスに対してgetName()
を呼べば定数の名前が返ってきます。あるいはgetReadable()
みたいなメソッドを個別に実装してもいいですし、多言語対応アプリの場合はtranslator
を使ってもいいですね。
Doctrine
定数値がstringならtype="string"
、intならtype="int"
とすると、永続化する際には使えるかもしれません(未確認)。しかし、ロードしたタイミングでEnumオブジェクトが出来上がって欲しいので、これは何かしら作らないとダメそう。
まとめ
GitHubでenumを検索してみると、PHPの実装は現在49個あるらしいです。早くPHPにもenumが実装されるといいですね。
ホーチミンは30度のクリスマスでした。それでは。
Merry Christmas and a Happy New Year.