code_junkie

PHP and Enums

Nov 12th, 2011
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.25 KB | None | 0 0
  1. class DaysOfWeek
  2. {
  3. const Sunday = 0;
  4. const Monday = 1;
  5. // etc.
  6. }
  7.  
  8. var $today = DaysOfWeek::Sunday;
  9.  
  10. <?php
  11.  
  12. class YourClass
  13. {
  14. const SOME_CONSTANT = 1;
  15.  
  16. public function echoConstant()
  17. {
  18. echo self::SOME_CONSTANT;
  19. }
  20. }
  21.  
  22. echo YourClass::SOME_CONSTANT;
  23.  
  24. $c = new YourClass;
  25. $c->echoConstant();
  26.  
  27. class SomeTypeName {
  28. private static $enum = array(1 => "Read", 2 => "Write");
  29.  
  30. public function toOrdinal($name) {
  31. return array_search($name, self::$enum);
  32. }
  33.  
  34. public function toString($ordinal) {
  35. return self::$enum[$ordinal];
  36. }
  37. }
  38.  
  39. class Enum {
  40. const NAME = 'aaaa';
  41. const SOME_VALUE = 'bbbb';
  42. }
  43.  
  44. print Enum::NAME;
  45.  
  46. <?php
  47.  
  48. /**
  49. * Class Enum
  50. *
  51. * @author Christopher Fox <[email protected]>
  52. *
  53. * @version 1.0
  54. *
  55. * This class provides the function of an enumeration.
  56. * The values of Enum elements are unique (even between different Enums)
  57. * as you would expect them to be.
  58. *
  59. * Constructing a new Enum:
  60. * ========================
  61. *
  62. * In the following example we construct an enum called "UserState"
  63. * with the elements "inactive", "active", "banned" and "deleted".
  64. *
  65. * <code>
  66. * Enum::Create('UserState', 'inactive', 'active', 'banned', 'deleted');
  67. * </code>
  68. *
  69. * Using Enums:
  70. * ============
  71. *
  72. * The following example demonstrates how to compare two Enum elements
  73. *
  74. * <code>
  75. * var_dump(UserState::inactive == UserState::banned); // result: false
  76. * var_dump(UserState::active == UserState::active); // result: true
  77. * </code>
  78. *
  79. * Special Enum methods:
  80. * =====================
  81. *
  82. * Get the number of elements in an Enum:
  83. *
  84. * <code>
  85. * echo UserState::CountEntries(); // result: 4
  86. * </code>
  87. *
  88. * Get a list with all elements of the Enum:
  89. *
  90. * <code>
  91. * $allUserStates = UserState::GetEntries();
  92. * </code>
  93. *
  94. * Get a name of an element:
  95. *
  96. * <code>
  97. * echo UserState::GetName(UserState::deleted); // result: deleted
  98. * </code>
  99. *
  100. * Get an integer ID for an element (e.g. to store as a value in a database table):
  101. * This is simply the index of the element (beginning with 1).
  102. * Note that this ID is only unique for this Enum but now between different Enums.
  103. *
  104. * <code>
  105. * echo UserState::GetDatabaseID(UserState::active); // result: 2
  106. * </code>
  107. */
  108. class Enum
  109. {
  110.  
  111. /**
  112. * @var Enum $instance The only instance of Enum (Singleton)
  113. */
  114. private static $instance;
  115.  
  116. /**
  117. * @var array $enums An array of all enums with Enum names as keys
  118. * and arrays of element names as values
  119. */
  120. private $enums;
  121.  
  122. /**
  123. * Constructs (the only) Enum instance
  124. */
  125. private function __construct()
  126. {
  127. $this->enums = array();
  128. }
  129.  
  130. /**
  131. * Constructs a new enum
  132. *
  133. * @param string $name The class name for the enum
  134. * @param mixed $_ A list of strings to use as names for enum entries
  135. */
  136. public static function Create($name, $_)
  137. {
  138. // Create (the only) Enum instance if this hasn't happened yet
  139. if (self::$instance===null)
  140. {
  141. self::$instance = new Enum();
  142. }
  143.  
  144. // Fetch the arguments of the function
  145. $args = func_get_args();
  146. // Exclude the "name" argument from the array of function arguments,
  147. // so only the enum element names remain in the array
  148. array_shift($args);
  149. self::$instance->add($name, $args);
  150. }
  151.  
  152. /**
  153. * Creates an enumeration if this hasn't happened yet
  154. *
  155. * @param string $name The class name for the enum
  156. * @param array $fields The names of the enum elements
  157. */
  158. private function add($name, $fields)
  159. {
  160. if (!array_key_exists($name, $this->enums))
  161. {
  162. $this->enums[$name] = array();
  163.  
  164. // Generate the code of the class for this enumeration
  165. $classDeclaration = "class " . $name . " {n"
  166. . "private static $name = '" . $name . "';n"
  167. . $this->getClassConstants($name, $fields)
  168. . $this->getFunctionGetEntries($name)
  169. . $this->getFunctionCountEntries($name)
  170. . $this->getFunctionGetDatabaseID()
  171. . $this->getFunctionGetName()
  172. . "}";
  173.  
  174. // Create the class for this enumeration
  175. eval($classDeclaration);
  176. }
  177. }
  178.  
  179. /**
  180. * Returns the code of the class constants
  181. * for an enumeration. These are the representations
  182. * of the elements.
  183. *
  184. * @param string $name The class name for the enum
  185. * @param array $fields The names of the enum elements
  186. *
  187. * @return string The code of the class constants
  188. */
  189. private function getClassConstants($name, $fields)
  190. {
  191. $constants = '';
  192.  
  193. foreach ($fields as $field)
  194. {
  195. // Create a unique ID for the Enum element
  196. // This ID is unique because class and variables
  197. // names can't contain a semicolon. Therefore we
  198. // can use the semicolon as a separator here.
  199. $uniqueID = $name . ";" . $field;
  200. $constants .= "const " . $field . " = '". $uniqueID . "';n";
  201. // Store the unique ID
  202. array_push($this->enums[$name], $uniqueID);
  203. }
  204.  
  205. return $constants;
  206. }
  207.  
  208. /**
  209. * Returns the code of the function "GetEntries()"
  210. * for an enumeration
  211. *
  212. * @param string $name The class name for the enum
  213. *
  214. * @return string The code of the function "GetEntries()"
  215. */
  216. private function getFunctionGetEntries($name)
  217. {
  218. $entryList = '';
  219.  
  220. // Put the unique element IDs in single quotes and
  221. // separate them with commas
  222. foreach ($this->enums[$name] as $key => $entry)
  223. {
  224. if ($key > 0) $entryList .= ',';
  225. $entryList .= "'" . $entry . "'";
  226. }
  227.  
  228. return "public static function GetEntries() { n"
  229. . " return array(" . $entryList . ");n"
  230. . "}n";
  231. }
  232.  
  233. /**
  234. * Returns the code of the function "CountEntries()"
  235. * for an enumeration
  236. *
  237. * @param string $name The class name for the enum
  238. *
  239. * @return string The code of the function "CountEntries()"
  240. */
  241. private function getFunctionCountEntries($name)
  242. {
  243. // This function will simply return a constant number (e.g. return 5;)
  244. return "public static function CountEntries() { n"
  245. . " return " . count($this->enums[$name]) . ";n"
  246. . "}n";
  247. }
  248.  
  249. /**
  250. * Returns the code of the function "GetDatabaseID()"
  251. * for an enumeration
  252. *
  253. * @return string The code of the function "GetDatabaseID()"
  254. */
  255. private function getFunctionGetDatabaseID()
  256. {
  257. // Check for the index of this element inside of the array
  258. // of elements and add +1
  259. return "public static function GetDatabaseID($entry) { n"
  260. . "$key = array_search($entry, self::GetEntries());n"
  261. . " return $key + 1;n"
  262. . "}n";
  263. }
  264.  
  265. /**
  266. * Returns the code of the function "GetName()"
  267. * for an enumeration
  268. *
  269. * @return string The code of the function "GetName()"
  270. */
  271. private function getFunctionGetName()
  272. {
  273. // Remove the class name from the unique ID
  274. // and return this value (which is the element name)
  275. return "public static function GetName($entry) { n"
  276. . "return substr($entry, strlen(self::$name) + 1 , strlen($entry));n"
  277. . "}n";
  278. }
  279.  
  280. }
  281.  
  282.  
  283. ?>
  284.  
  285. $value = "concert";
  286. $Enumvalue = EnumCategory::enum($value);
  287. //$EnumValue = 1
  288.  
  289. class EnumCategory{
  290. const concert = 1;
  291. const festival = 2;
  292. const sport = 3;
  293. const nightlife = 4;
  294. const theatre = 5;
  295. const musical = 6;
  296. const cinema = 7;
  297. const charity = 8;
  298. const museum = 9;
  299. const other = 10;
  300.  
  301. public function enum($string){
  302. return constant('EnumCategory::'.$string);
  303. }
  304. }
  305.  
  306. class EnumCategory {
  307.  
  308. static $concert = 1;
  309. static $festival = 2;
  310. static $sport = 3;
  311. static $nightlife = 4;
  312. static $theatre = 5;
  313. static $musical = 6;
  314. static $cinema = 7;
  315. static $charity = 8;
  316. static $museum = 9;
  317. static $other = 10;
  318.  
  319. }
  320.  
  321. EnumCategory::${$category};
  322.  
  323. <?php
  324. //require the library
  325. require_once __DIR__ . '/src/Enum.func.php';
  326.  
  327. //if you don't have a cache directory, create one
  328. @mkdir(__DIR__ . '/cache');
  329. EnumGenerator::setDefaultCachedClassesDir(__DIR__ . '/cache');
  330.  
  331. //Class definition is evaluated on the fly:
  332. Enum('FruitsEnum', array('apple' , 'orange' , 'rasberry' , 'bannana'));
  333.  
  334. //Class definition is cached in the cache directory for later usage:
  335. Enum('CachedFruitsEnum', array('apple' , 'orange' , 'rasberry' , 'bannana'), 'mycompanynamespace', true);
  336.  
  337. echo 'FruitsEnum::APPLE() == FruitsEnum::APPLE(): ';
  338. var_dump(FruitsEnum::APPLE() == FruitsEnum::APPLE()) . "n";
  339.  
  340. echo 'FruitsEnum::APPLE() == FruitsEnum::ORANGE(): ';
  341. var_dump(FruitsEnum::APPLE() == FruitsEnum::ORANGE()) . "n";
  342.  
  343. echo 'FruitsEnum::APPLE() instanceof Enum: ';
  344. var_dump(FruitsEnum::APPLE() instanceof Enum) . "n";
  345.  
  346. echo 'FruitsEnum::APPLE() instanceof FruitsEnum: ';
  347. var_dump(FruitsEnum::APPLE() instanceof FruitsEnum) . "n";
  348.  
  349. echo "->getName()n";
  350. foreach (FruitsEnum::iterator() as $enum)
  351. {
  352. echo " " . $enum->getName() . "n";
  353. }
  354.  
  355. echo "->getValue()n";
  356. foreach (FruitsEnum::iterator() as $enum)
  357. {
  358. echo " " . $enum->getValue() . "n";
  359. }
  360.  
  361. echo "->getOrdinal()n";
  362. foreach (CachedFruitsEnum::iterator() as $enum)
  363. {
  364. echo " " . $enum->getOrdinal() . "n";
  365. }
  366.  
  367. echo "->getBinary()n";
  368. foreach (CachedFruitsEnum::iterator() as $enum)
  369. {
  370. echo " " . $enum->getBinary() . "n";
  371. }
  372.  
  373. FruitsEnum::APPLE() == FruitsEnum::APPLE(): bool(true)
  374. FruitsEnum::APPLE() == FruitsEnum::ORANGE(): bool(false)
  375. FruitsEnum::APPLE() instanceof Enum: bool(true)
  376. FruitsEnum::APPLE() instanceof FruitsEnum: bool(true)
  377. ->getName()
  378. APPLE
  379. ORANGE
  380. RASBERRY
  381. BANNANA
  382. ->getValue()
  383. apple
  384. orange
  385. rasberry
  386. bannana
  387. ->getValue() when values have been specified
  388. pig
  389. dog
  390. cat
  391. bird
  392. ->getOrdinal()
  393. 1
  394. 2
  395. 3
  396. 4
  397. ->getBinary()
  398. 1
  399. 2
  400. 4
  401. 8
  402.  
  403. class FruitsEnum {
  404.  
  405. static $APPLE = null;
  406. static $ORANGE = null;
  407.  
  408. private $value = null;
  409.  
  410. public static $map;
  411.  
  412. public function __construct($value) {
  413. $this->value = $value;
  414. }
  415.  
  416. public static function init () {
  417. self::$APPLE = new FruitsEnum("Apple");
  418. self::$ORANGE = new FruitsEnum("Orange");
  419. //static map to get object by name - example Enum::get("INIT") - returns Enum::$INIT object;
  420. self::$map = array (
  421. "Apple" => self::$APPLE,
  422. "Orange" => self::$ORANGE
  423. );
  424. }
  425.  
  426. public static function get($element) {
  427. if($element == null)
  428. return null;
  429. return self::$map[$element];
  430. }
  431.  
  432. public function getValue() {
  433. return $this->value;
  434. }
  435.  
  436. public function equals(FruitsEnum $element) {
  437. return $element->getValue() == $this->getValue();
  438. }
  439.  
  440. public function __toString () {
  441. return $this->value;
  442. }
  443. }
  444. FruitsEnum::init();
  445.  
  446. var_dump(FruitsEnum::$APPLE->equals(FruitsEnum::$APPLE)); //true
  447. var_dump(FruitsEnum::$APPLE->equals(FruitsEnum::$ORANGE)); //false
  448. var_dump(FruitsEnum::$APPLE instanceof FruitsEnum); //true
  449. var_dump(FruitsEnum::get("Apple")->equals(FruitsEnum::$APPLE)); //true - enum from string
  450. var_dump(FruitsEnum::get("Apple")->equals(FruitsEnum::get("Orange"))); //false
Add Comment
Please, Sign In to add comment