例えばデータベースに下のようなテーブルを定義したときに、
0が犬、1が猫、2がロバを表していることを(C言語のenumのように)簡潔に表現できる型が欲しくなりますよね。
テーブル:my_friends
id (数値) | name (文字列) | type (数値) |
---|---|---|
1 | ポチ | 0(犬) |
2 | 猫太郎 | 1(猫) |
3 | ルシオ | 2(ロバ) |
PHP5.6以降の場合
PHP5.6以降では、arrayにconstを指定できるようになったので、
enumセットをconstなarrayとして定義すると使い勝手が良いです。
(const指定した値は、定数なので$を付けずに使います。)
参考: PHPマニュアル PHP 5.5.xからPHP 5.6.x への移行 http://php.net/manual/ja/migration56.new-features.php
Enum定義サンプル:
<?php
//------------------------------------------------------
// Enum値の定義
//
// constなarrayを作るだけです
//
const FiendType = array(
'Dog' => 1,
'Cat'=> 2,
'Asinus' => 3,
'Human' => 10
);
//------------------------------------------------------
// Enum値を使う
//
$type = FriendType['Cat']; // typeに猫を設定します
// switch文でtype別の発言をprintしてみます
switch ($type) {
case FriendType['Dog']:
print "ワン\n";
break;
case FriendType['Cat']:
print "ニャー\n";
break;
case FriendType['Asinus']:
print "グーヒー、グーヒー\n";
break;
}
?>
※ 配列要素の参照方法が間違っていたので修正しました。PHP5.5以前の場合
5.5より前のバージョンのPHPではconstなarrayは定義できないようなので、
arrayの値を変更できないように保護するクラスを作ってみました。
<?php
//
// PHP(5.5)でEnumを使うためのクラス
//
class Enum
{
//
// Enumオブジェクトの生成
//
private static $enums = array();
public static function __callStatic($name, $arguments)
{
if (is_array($arguments[0])) {
// 重複チェック
if (isset(self::$enums[$name])) {
trigger_error(print "{$name} is exists..", E_USER_ERROR);
}
self::$enums[$name] = new Enum($arguments[0]);
} else {
if (!isset(self::$enums[$name])) {
trigger_error("Enum {$name} not found...", E_USER_ERROR);
}
return self::$enums[$name];
}
}
//
// Enumオブジェクトのメソッド
//
protected $values = array(); // Enum要素
// arrayからEnumオブジェクトを生成
protected function __construct(array $params)
{
// Enum値をプロパティへ
foreach ($params as $key => $p) {
if (!is_int($key)) {
trigger_error('Key must be an int.', E_USER_ERROR);
}
$this->values[$p] = $key;
}
}
// Enum要素の取得
public function __get($name)
{
if (!isset($this->values[$name])) {
// 存在しない要素
trigger_error("[{$name}] isn't enum element", E_USER_ERROR);
}
return $this->values[$name];
}
// 代入
public function __set($name, $value)
{
trigger_error("Enum can't set.", E_USER_ERROR);
}
}
?>
実際に連番を定義する時には、下のように使います。
<?php
//
// 連番の定義
//
// Enum::'連番の名前'()に対して、arrayを渡すだけです。
//
Enum::FriendType(
array(
'Dog', // 犬
'Cat', // 猫
'Asinus', // ロバ
10 => 'Human' , //いつか人間のFriendができた時のために10番をHumanにしておく、なんてこともできます
)
);
?>
Enum::のあとにEnumセットの名前を書いて()の中にEnum要素の名前を配列として渡すだけです。配列のキーがそのまま各要素の値になっているので、上のHUMANのようにキーを指定すれば、
値を指定した要素を作ることもできます。
上で定義した連番を使う場合は、下のようになります。
<?php
$type = Enum::FriendType()->Cat; // typeに猫を設定します
// switch文でtype別の発言をprintしてみます
switch ($type) {
case Enum::FriendType()->Dog:
print "ワン\n";
break;
case Enum::FriendType()->Cat:
print "ニャー\n";
break;
case Enum::FriendType()->Asinus:
print "グーヒー、グーヒー\n";
break;
}
?>
ここでも、Enum::のあとにEnumセットの名前と()を書き、->で各要素にアクセスします。もっとオブジェクト指向なJava風Enum(Enamlatableなオブジェクト)を定義したいって時は、PHPでJava風のEnum(なごりんぐ)へ。