note 78253 deleted from language.oop5 by felipe
| From: | felipe@php.net | Date: | Mon, 24 Mar 2008 22:10:13 +0000 |
| Subject: | note 78253 deleted from language.oop5 by felipe | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-137466@lists.php.net to get a copy of this message | ||
Note Submitter: muratyaman at gmail dot com
----
Subject: TYPE HINTING, ENUMS, READABILITY
Uses: REFLECTION, MAGIC FUNCTIONS, EXCEPTIONS, ARRAYS.
<?php
/**
* Natural definition in PHP, similar to an ENUM definition
*/
final class FAKE_ENUM_DAY {
const MONDAY = 1;
const TUESDAY = 2;
const WEDNESDAY = 4;
const THURSDAY = 8;
const FRIDAY = 16;
}
/**
* Better definition of an ENUM
*/
class REAL_ENUM_DAY
{
const MONDAY = 1;
const TUESDAY = 2;
const WEDNESDAY = 4;
const THURSDAY = 8;
const FRIDAY = 16;
private $option;
private $value;
private $options;
/**
* Constructor
* @param string/int $option_or_value
* If input is string
*/
function __construct($option_or_value){
$ref = new ReflectionClass('REAL_ENUM_DAY');
$this->options = $ref->getConstants();
$i = $option_or_value;
if(is_int($i)){
$option = array_search($i, $this->options);
if(isset($this->options[$option])){
$this->option = $option;
$this->value = $this->options[$option];
}else{
throw new Exception('Invalid day index!');
}
}else{//if(is_string($i)){
if(isset($this->options[$i])){
$this->option = $i;
$this->value = $this->options[$i];
}else{
throw new Exception('Invalid day name!');
}
}
}
/**
* Proper comparison function for the class
*/
public static function compare(REAL_ENUM_DAY $day1, REAL_ENUM_DAY $day2){
return ($day1->day() === $day2->day());
}
public function day(){
return $this->value;
}
/**
* More flexible comparison
*/
public function on($when){
if(is_int($when))
return ($this->value === $when);
elseif($when instanceof self)
return ($this->value === $when->day());
else
throw new Exception('Invalid input!');
}
/**
* Handy function to use enum class as string
*/
public function __toString(){
return ucfirst(strtolower($this->option));
}
}
class Person{
public $name;
function __construct($name){
$this->name = $name;
}
}
class Place{
public $name;
function __construct($name){
$this->name = $name;
}
}
function meet(Person $who, Place $where, FAKE_ENUM_DAY $when){
return 'This will not be successful!<br>';
}
echo meet(new Person('Murat'), new Place('London')
, FAKE_ENUM_DAY::MONDAY);//PHP: INVALID ARGUMENT TYPE
/**
* MUST HAVE FEATURE OF ENUMS:
* 1. .. TO BE USED AS PARAMETER TYPES
* HENCE, RESTRICT THE PARAMETER VALUES
* 2. .. TO MAKE THE CODE MORE READABLE WHILE WRITING IT
*/
class Meeting{
private $who;
private $where;
private $when;
function __construct(Person $who, Place $where, REAL_ENUM_DAY $when){
$this->who = $who;
$this->where = $where;
$this->when = $when;
//if($when === REAL_ENUM_DAY::TUESDAY){//WON'T WORK
if($when->on(REAL_ENUM_DAY::TUESDAY)){//WORKS
//if($when.'' === ''.new REAL_ENUM_DAY('TUESDAY')){//WORKS
//if(REAL_ENUM_DAY::compare($when, new REAL_ENUM_DAY(REAL_ENUM_DAY::TUESDAY))){
throw new Exception("$this->when is not good :(");
}
}
function __toString(){
return "Meeting {$this->who->name} in {$this->where->name} on
{$this->when}";
}
}
echo new Meeting(new Person('Murat'), new Place('London')
, new REAL_ENUM_DAY(REAL_ENUM_DAY::MONDAY)).'.<br />';//WORKS
echo new Meeting(new Person('Esra'), new Place('Paris')
, new REAL_ENUM_DAY('TUESDAY')).'.<br />';//CUSTOME EXCEPTION
echo new Meeting(new Person('Mehmed'), new Place('Istanbul')
, new REAL_ENUM_DAY(REAL_ENUM_DAY::SUNDAY)).'.<br />';//PHP: UNDEFINED CONSTANT
echo new Meeting(new Person('Yaman'), new Place('Aksaray')
, 8).'.<br />';//PHP: INVALID ARGUMENT TYPE
?>