Skip to content

Typesafe enumerations (PHP5) #9

@thekid

Description

@thekid

Scope of Change

A new keyword enum is introduced.

Rationale

Replace classes like the util.MimeType class that consist of defines
and utility functions only.

Functionality

Enumerations have a static function "size()" that returns the number of
members in the enumeration.

Using the size() method:

<?php
  enum CoinColor { copper, nickel, silver }

  echo CoinColor::size();
?>

The above example prints out the following:

  3

Enumerations have a static function "values()" that returns the values
as an array.

Using the values() method:

<?php
  function nameOf($member) {
    return $member->name;
  }

  enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES }

  echo implode(', ', array_map('nameOf', Suit::values()));
?>

The above example prints out the following:

  CLUBS, DIAMONDS, HEARTS, SPADES

Enumerations have a static function "valueOf()" that returns the value
of a single member.

Using the valueOf() method:

<?php
  function nameOf($member) {
    return $member->name;
  }

  enum Day { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }

  foreach (range(Monday, Friday) as $day) {
    echo $day, ': ', nameOf(Day::valueOf($day)), "\n";
  }
?>

The above example prints out the following:

  0: Monday
  1: Tuesday
  2: Wednesday
  3: Thursday
  4: Friday

Enumerations members may have a value associated with them.

Using the value:

<?php
  function colorOf($coin) {
    switch ($coin->ordinal) {
      case penny: return 'copper';
      case nickel: return 'nickel';
      case dime: case quarter: return 'silver';
    }
  }

  enum Coin {
    penny(1), nickel(5), dime(10), quarter(25);

    var $value= 0;

    function __construct($name, $value) { 
      parent::__construct($name); 
      $this->value= $value; 
    }

    function value() { return $this->value; }
  }

  foreach (Coin::values() as $coin) {
    echo $coin->name, ': ', $coin->value(), '¢ (', colorOf($coin), ")\n";
  }
?>

The above example prints out the following:

  penny: 1¢ (copper)
  nickel: 5¢ (nickel)
  dime: 10¢ (silver)
  quarter: 25¢ (silver)

Enumeration members may declare methods.

<?php
  enum Operation {
    plus { 
      function evaluate($x, $y) { return $x + $y; } 
    }
    minus { 
      function evaluate($x, $y) { return $x - $y; } 
    }
    times { 
      function evaluate($x, $y) { return $x * $y; } 
    }
    divided_by { 
      function evaluate($x, $y) { return $x / $y; } 
    }

    function evaluate($x, $y);
  }

  $x= 2;
  $y= 4;
  foreach (Operation::values() as $op) {
    printf("%d %s %s = %.1f\n", $x, $op->name, $y, $op->evaluate($x, $y));
  }
?>

The above example prints out the following:

  2 plus 4 = 6.0
  2 minus 4 = -2.0
  2 times 4 = 8.0
  2 divided_by 4 = 0.5

Implementation notes

Implementation has been included in the ZendEngine patch contained in this
CVS repository.

Enumerations technically are special classes that have the final methods size(),
valueOf() and valueAt() - as well as the properties name, ordinal and value. Every
enumeration class derives from class Enumeration (a package for these has yet to
be defined).

When declaring an enumeration type, one can omit the actual value of some or all
enumeration members - if omitted, a default value is calculated by taking the maximum
value seen so far and adding 1 to that value. Each value has to be unique to ensure
a correct mapping via the valueOf() method.

Allowed values are integers and strings. If other scalars (and only those are
allowed by the parser) are submitted, they'll be casted to string.

An enumeration member method internally is renamed to
"__{enumerationname}{methodname}". Access is being delegated by implementing a __call()
method in the enumerations class. Thus, by overriding __call() you could change the
way enumerated methods are accessed.

Related documents

  • A Typesafe Enum Facility for the Java[tm] Programming Language
    http://jcp.org/aboutJava/communityprocess/jsr/tiger/enum.html
  • Syntax and functionality demonstration examples can be found in
    experiments/arena/php5/enum (Note: these differ from the syntax examples given
    in this rfc; those are not 100% correct in respect to the final implementation).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions