PHP Type Safe Enum
This snippet provides a simple implementation of type safe enums for PHP 5.3.
Snippet
Abstraction
The Enum base class.
// (c) Copyright 2011 Bedican Solutions (www.bedican.co.uk)
abstract class Enum
{
private static $registered = false;
private static $values = array();
private final function __construct($args)
{
$this->init($args);
}
protected abstract function init($args);
protected abstract static function addValues();
private static function register()
{
if(!self::$registered) {
self::$registered = true;
static::addValues();
}
}
protected static function addValue($name, $args = array())
{
$className = get_called_class();
self::$values[$name] = new $className($args);
}
public static function getValues()
{
self::register();
return array_values(self::$values);
}
public static function __callStatic($name, $args)
{
self::register();
if(!array_key_exists($name, self::$values)) {
throw new EnumNotFoundException('Unknown enum value '.get_called_class().'::'.$name);
}
return self::$values[$name];
}
}
class EnumNotFoundException extends Exception
{
}
Implementing Class
A class representing a http status.
// (c) Copyright 2011 Bedican Solutions (www.bedican.co.uk)
class HttpStatus extends Enum
{
private $code;
private $message;
protected function init($args)
{
list($this->code, $this->message) = $args;
}
public function getCode()
{
return $this->code;
}
public function getMessage()
{
return $this->message;
}
public function toString()
{
return $this->getCode().' '.$this->getMessage();
}
public function __toString()
{
return $this->toString();
}
public static function getHttpStatus($code)
{
$values = self::getValues();
foreach($values as $value) {
if($value->getCode() == $code) {
return $value;
}
}
return null;
}
protected static function addValues()
{
// 2xx OK
self::addValue('OK', array(200, 'OK'));
self::addValue('CREATED', array(201, 'Created'));
self::addValue('ACCEPTED', array(202, 'Accepted'));
self::addValue('NON_AUTHORATIVE', array(203, 'Non-Authoritative Information'));
self::addValue('NO_CONTENT', array(204, 'No Content'));
self::addValue('RESET_CONTENT', array(205, 'Reset Content'));
self::addValue('PARTIAL_CONTENT', array(206, 'Partial Content'));
// 3xx Redirection
self::addValue('MUTIPLE_CHOICES', array(300, 'Multiple Choices'));
self::addValue('MOVED_PERMANENTLY', array(301, 'Moved Permanently'));
self::addValue('FOUND', array(302, 'Found'));
self::addValue('SEE_OTHER', array(303, 'See Other'));
self::addValue('NOT_MODIFIED', array(304, 'Not Modified'));
self::addValue('USE_PROXY', array(305, 'Use Proxy'));
self::addValue('TEMPORARY_REDIRECT', array(307, 'Temporary Redirect'));
// 4xx Client Error
self::addValue('BAD_REQUEST', array(400, 'Bad Request'));
self::addValue('UNAUTHORIZED', array(401, 'Unauthorized'));
self::addValue('PAYMENT_REQUIRED', array(402, 'Payment Required'));
self::addValue('FORBIDDEN', array(403, 'Forbidden'));
self::addValue('NOT_FOUND', array(404, 'Not Found'));
self::addValue('METHOD_NOT_ALLOWED', array(405, 'Method Not Allowed'));
self::addValue('NOT_ACCEPTABLE', array(406, 'Not Acceptable'));
self::addValue('PROXY_AUTHENTICATION_REQUIRED', array(407, 'Proxy Authentication Required'));
self::addValue('REQUEST_TIMEOUT', array(408, 'Request Timeout'));
self::addValue('CONFLICT', array(409, 'Conflict'));
self::addValue('GONE', array(410, 'Gone'));
self::addValue('LENGTH_REQUIRED', array(411, 'Length Required'));
self::addValue('PRECONDITION_FAILED', array(412, 'Precondition Failed'));
self::addValue('ENTITY_TOO_LARGE', array(413, 'Request Entity Too Large'));
self::addValue('URI_TOO_LONG', array(414, 'Request-URI Too Long'));
self::addValue('UNSUPPORTED_MEDIA_TYPE', array(415, 'Unsupported Media Type'));
self::addValue('RANGE_NOT_SATISFIABLE', array(416, 'Requested Range Not Satisfiable'));
self::addValue('EXPECTATION_FAILED', array(417, 'Expectation Failed'));
// 5xx Server Error
self::addValue('INTERNAL_SERVER_ERROR', array(500, 'Internal Server Error'));
self::addValue('NOT_IMPLEMENTED', array(501, 'Not Implemented'));
self::addValue('BAD_GATEWAY', array(502, 'Bad Gateway'));
self::addValue('SERVICE_UNAVAILBLE', array(503, 'Service Unavailable'));
self::addValue('GATEWAY_TIMEOUT', array(504, 'Gateway Timeout'));
self::addValue('VERSION_NOT_SUPPORTED', array(505, 'HTTP Version Not Supported'));
}
}
Example Usage
Both $okStatus and $notFoundStatus are instances of HttpStatus.
$okStatus = HttpStatus::OK(); $notFoundStatus = HttpStatus::NOT_FOUND(); print($okStatus->getCode()); // 200 print($notFoundStatus->getCode()); // 404
