型チェックを使用したPHPの列挙型実装

コードで厳密に型指定されたパラメーターを使用する必要がある場合がありますが、PHP言語自体は厳密に型指定されていません(たとえば、enum-Enumなどのデータ型があるC#など)。 ただし、この状況から抜け出す方法はまだあります。 インターネットを介して大騒ぎして、私に適したソリューションが見つかりませんでした。 この問題に対する私の解決策を提供します。



問題は次のとおりでした。 入力として厳密に型指定されたオブジェクト(クラス)を受け入れる関数を実装する必要がありますが、関数の本体では、このクラスの値を列挙し、定義済みの定数(同じクラス)と比較する必要があります。



function test(Data $data) { switch ((string)$data) { case Data::ID: echo 'This is ID' . PHP_EOL; break; case Data::STRING: echo 'This is a STRING' . PHP_EOL; break; } }
      
      







ただし、PHPがswitch



パラメーターとしてオブジェクトを使用できないことを警告することがすぐに明らかになります。



この問題の解決策は、事前定義された定数が使用される抽象クラスをすべてのクラスの基本クラスとして実装し、 switch



で比較を行うことです。



このクラスのコード:



 /** * Base class, witch implements enumeration in child classes. * * PHP version 5 * * @author Andrey Klimenko * @license 2012, Andrey Klimenko * @version 1.0.0 */ abstract class AbstractEnum { /** * @var AbstractEnum Class instance */ protected static $instance = null; /** * @var mixed Value to compare with class constants */ protected static $value; /** * Protected constructor (realize singleton pattern). * * @final */ protected final function __construct() { } /** * Protect from object cloning (realize singleton pattern). * * @final */ protected final function __clone() { } /** * Protect from reconstruct resources that the object may have (realize singleton pattern). * * @final */ protected final function __wakeup() { } /** * Return instance of this object. * * @static * * @param mixed $value Constant value * * @return AbstractEnum */ public static function getInstance($value) { if (self::$instance === null) { self::$instance = new static(); } self::setConstant($value); // Set value of constant return self::$instance; } /** * Prepare to return constant value, given in getInstance() function. * * @return string */ public final function __toString() { return (string)static::$value; } /** * Set constant value. * * @static * * @param mixed $value Constant value * */ protected static function setConstant($value) { $class = new \ReflectionClass(static::$instance); // Get this class reflection $constants = array_flip($class->getConstants()); // Get constants of this object // Check if constant with given value exist if (array_key_exists($value, $constants)) { $constantName = $constants[$value]; static::$value = $class->getConstant($constantName); // Set constant value } else { trigger_error('Class does not have constant with this value: `' . $value . '`', E_USER_ERROR); } } }
      
      







ここで、上記の抽象クラスを継承するクラスを実装します。 このクラスは、比較する定数を含むクラスです。



 /** * Sample class, witch implement AbstractEnum abstract class. * * PHP version 5 * * @author Andrey Klimenko * @license 2012, Andrey Klimenko * @version 1.0.0 */ class Data extends AbstractEnum { const ID = 1; // First constant const STRING = 2; // Second constant }
      
      







次に、クラスの動作をチェックする関数を実装します。 主な問題は、私が言ったように、渡されるパラメーターの厳密な型指定でした。 型として、クラスData



を示します。



 /** * Test function. * * @param Data $data Class to check value with. * * @return void */ function test(Data $data) { // First - convert object to string switch ((string)$data) { // compare needed values case Data::ID: echo 'This is ID' . PHP_EOL; break; case Data::STRING: echo 'This is a STRING' . PHP_EOL; break; } }
      
      







最後に、機能を確認します。



 for ($i = 1; $i < 3; $i++) { test(Data::getInstance($i)); }
      
      







すべてが望みどおりに機能します。 以上です。 このデザインがお役に立てば幸いです。



All Articles