Created
February 21, 2012 07:25
-
-
Save cignoir/1874771 to your computer and use it in GitHub Desktop.
PHP5.2でenumを実装してみるテスト
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Enum のベースクラス | |
* | |
*/ | |
abstract class Enum { | |
public $code; | |
public $name; | |
private static $instances = array(); | |
protected static function setUp() { | |
// StackTraceからCall元のEnumのサブクラス名を取得する | |
// PHP5.3以上ならget_called_class()が使える | |
$stack = debug_backtrace(); | |
$className = $stack[1]['class']; | |
// 取得したクラス名をもとにリフレクションでインスタンスを生成する | |
$class = new ReflectionClass($className); | |
// アクセス修飾子を問わずすべての静的メンバを動的に取得する | |
$types = $class->getStaticProperties(); | |
// プロパティ名の配列を取得する | |
$keys = array_keys($types); | |
for ($i = 0; $i < count($keys); $i++) { | |
/** | |
* プロパティごとにインスタンスを生成しnameをセットしたあと | |
* $instances にそのインスタンスを保持 | |
*/ | |
$obj = new $className(); | |
$obj->code = $className . '@' . $i; | |
$obj->name = $keys[$i]; | |
if ($class->hasProperty($keys[$i])) { | |
$class->setStaticPropertyValue($keys[$i], $obj); | |
} | |
self::$instances[$keys[$i]] = $obj; | |
} | |
} | |
public function equals(Enum $obj) { | |
return $this->code === $obj->code; | |
} | |
public function __toString() { | |
return $this->name; | |
} | |
} | |
/* | |
独自のEnumの定義 | |
<?php | |
require_once 'Enum.php'; | |
class Fruits extends Enum { | |
// 列挙子を静的プロパティとして定義 | |
public static $APPLE, $BANANA, $ORANGE; | |
public static function setUp() { | |
parent::setUp(); | |
} | |
} | |
// 静的プロパティの動的初期化(必須) | |
Fruits::setUp(); | |
?> | |
定義したEnumを使ってみる | |
<?php | |
require_once 'Fruits.php'; | |
// タイプヒンティング活用 | |
function eat(Fruits $fruits) { | |
// 等価性はEnumの$codeの値で比較される | |
if ($fruits->equals(Fruits::$APPLE)) { | |
// __toStringをオーバーライドしてるので | |
// $nameの比較であれば===でもOK | |
echo $fruits === Fruits::$APPLE; | |
} else { | |
} | |
} | |
*/ | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment