Skip to content

Instantly share code, notes, and snippets.

@cignoir
Created February 21, 2012 07:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cignoir/1874771 to your computer and use it in GitHub Desktop.
Save cignoir/1874771 to your computer and use it in GitHub Desktop.
PHP5.2でenumを実装してみるテスト
<?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