PHP Classes

Typesafe Enum: Implement enumerated values as class functions

Recommend this page to a friend!
  Info   View files View files (9)   DownloadInstall with Composer Download .zip   Reputation   Support forum (2)   Blog    
Last Updated Ratings Unique User Downloads Download Rankings
2010-07-07 (7 years ago) RSS 2.0 feedNot yet rated by the usersTotal: 383 All time: 6,441 This week: 813Up
Version License PHP version Categories
typesafe-enum 1.1BSD License5.2.5PHP 5, Data types, Code Generation
Description Author

This class can be used to implement enumerated values as class functions.

It takes the name of a class and the list of names for enumerated values to define and generates code for a new class that defines the enumerated values.

The enumerated values can be retrieved using static function calls to the generated class.

Innovation Award
PHP Programming Innovation award nominee
March 2010
Number 5

Prize: One book of choice by Packt
Enumerated values can be used to assign meaningful values to variables that only accept a limited number of values.

An alternative way to implement enumerated value types by using class functions to represent each enumerated value.

Manuel Lemos
  Performance   Level  
Name: Fabian Schmengler is available for providing paid consulting. Contact Fabian Schmengler .
Classes: 6 packages by
Country: Germany Germany
Age: 34
All time rank: 105266 in Germany Germany
Week rank: 335 Up15 in Germany Germany Up
Innovation award
Innovation award
Nominee: 4x

|                             Typesafe Enum                                    |

- Synopsis
- Requirements
- Files
- Simple Usage: Generation
- Extended Usage: Methods
- Extended Usage: Configuration
- Extended Usage: Manual Definition
- Performance

This package is an implementation of the Typesafe Enum Pattern known from JAVA
before it had its own Enum type. The Enum class can be used as base class to
implement typesafe enumerations easily in PHP and also to generate them

If you are not familiar with the pattern, I recommend reading this explanation
of the JAVA pattern:

The package requires PHP 5.2.6 or later.

It depends on the following functionality from PHP > 5.0:

5.2.5: debug_backtrace() parameter in Enum::define() and Enum::___get()
5.2.0: recursive mkdir in Enum::___writeToCache()
5.1.0: InvalidArgumentException from SPL in Enum::define() and Enum::valuesOf()
5.1.0: LOCK_EX flag in Enum::___writeToCache()
5.1.0: array_intersect_key in array_iunique
5.0.3: is_subclass_of in define_once and valuesOf

If you remove the respective optional parameters from debug_backtrace and mkdir
and don't set Enum::$cacheReUsePackagePath, the package works fine on PHP 5.1.0

Workarounds to get the package running on PHP 5.0 should also be possible but
are not recommended.

typesafeenum.lib.php - library loader, include this file to use the package
Enum.php - Enum base class and generator
cache/ - empty directory where the cached class files go. Must be writable!
example/example.php - Example to demonstrate simple usage
test/EnumTest.php - PHPUnit test case
test/EnumBenchmark.php - Benchmark class
test/run_benchmark.php - The script that I used for performance tests
license.txt - BSD License
readme.txt - the file you are reading right now

Simple Usage: Generation
Typical usage of the generator:

	Enum::define('MyEnum', 'Value1', 'Value2', 'Value3', 'Value4');
	function doSomething(MyEnum $myenum) {
		echo (string) $myEnum;
		switch ($myenum) {
			case MyEnum::Value1():
				// do something for Value1
			case MyEnum::Value2():
				// do something for Value2
			case MyEnum::Value3():
				// do something for Value3
			case MyEnum::Value4():
				// do something for Value4

You can configure the behaviour of the generator with class variables of Enum,
the most important one is $cacheEnabled. It is true by default but you may want
to turn caching off, so that eval() will be used with the generated code
instead of cached files.

	Enum::$cacheEnabled = false;

Extended Usage: Methods
Besides define() there are two other public static methods in Enum:

	define_once(string $enumName, string $value1, string $value2, ... )

define_once works exactly like define but does nothing if the given Enumeration
already is defined, similar to include_once and require_once.

	valuesOf(string $enumName)

valuesOf returns all values (instances) of the given enumeration class.

Extended Usage: Configuration
The caching can be configured with the following class variables:

	bool $checkCache: Check if cached files are outdated (you may want to disable
		this in productive environment). Defaults to true

	string $cacheDir: Where the generated files should be stored (path relative to
		this file). Defaults to 'cache'
	bool $cacheReUsePackagePath: If package path should be mapped to cache dir
		Useful if the same Enum names can occur in different packages. Defaults to
		false. Example:

		// in package1/subpackage/class.php:
		Enum::$cacheReUsePackagePath = true;
		Enum::define('MyEnum', 'FOO', 'BAR');

		// in package2/otherclass.php:
		Enum::$cacheReUsePackagePath = true;
		Enum::define('MyEnum', 'MOO', 'NARF');

		Now there will be two separate cached files:
		- cache/package1/subpackage/MyEnum.php
		- cache/package2/MyEnum.php

		Of course both packages cannot be used simultaneous since we don't have
		namespaces here.

	string $cachePackageRoot: Package root (necessary for $cacheReUsePackagePath).
		Defines from where the path should be reused.

Extended Usage: Manual Definition
There are several scenarios where generating Enum classes with Enum::define()
is not sufficient:
	- If you are using many Enum classes and need maximum performance (see next
	- If your system does not allow creation of files or eval()
	- If you want to use the Enum classes in a more flexible way (i.e.
	  implementing a Comparable interface)

In these cases you can easily define them yourself like that:

	final class MyEnum extends Enum
		public static final function VALUE1() {
			return self::___get('MyEnum', 'VALUE1');
		public static final function VALUE2() {
			return self::___get('MyEnum', 'VALUE2');
		public static final function VALUE3() {
			return self::___get('MyEnum', 'VALUE3');

The parameters of ___get may be omitted, then the calling class and method will
be determined automatically. If you add own functionality you can get the value
of the current instance with


Usually you should not worry about performance issues with the generator except
you define really many Enums in a time-critical environment. Then you may
consider resorting to manual definition.
To decide if caching is the right choice you can test the speed on your system
by running test/run_benchmark.php - you may want to change the first lines
beforehand to determine the number of defined Enum classes.
Note that depending on the filesystem caching does not necessary give an
advantage, so the decision may be based on other factors.
  Files folder image Files  
File Role Description
Files folder imageexample (1 file)
Files folder imagetest (3 files)
Files folder imagecache (1 file)
Accessible without login Plain text file readme.txt Doc. Full documentation
Plain text file license.txt Lic. BSD License
Plain text file typesafeenum.lib.php Aux. Include this file to use the package
Plain text file Enum.php Class Enum base class and generator

  Files folder image Files  /  example  
File Role Description
  Accessible without login Plain text file example.php Example Simple example usage

  Files folder image Files  /  test  
File Role Description
  Plain text file EnumBenchmark.php Class Benchmark class
  Plain text file EnumTest.php Test PHPUnit test class
  Plain text file run_benchmark.php Aux. The script that I used for benchmarking

  Files folder image Files  /  cache  
File Role Description
  Plain text file EMPTY Data make this directory writable for PHP

 Version Control Reuses Unique User Downloads Download Rankings  
This week:0
All time:6,441
This week:813Up
User Comments (1)