Requests for comment/Typesafe enums

Implemented and merged on a WIP branch of the Campaigns extension for the Editor campaigns project; now benchmarking and adding requested features

This RFC proposes a mechanism for creating typesafe enums. An implementation with tests and examples is provided.

Problem statement
By using enums, you can improve code in several ways. Many languages have native enum constructs, but PHP doesn't. In MediaWiki, class constants are usually used instead. However, PHP developers often roll enum implementations that are as good or nearly as good as native constructs in other languages.

Adding enum facilities to core would provide MediaWiki code the benefits of fully featured enums, including type safety, information hiding, meaningful conversion to strings, helper functions on sets of enum values, and extensibility.

Options
Options include:
 * Do nothing. There's nothing inherently wrong with class constants.
 * Use PHP's experimental SplEnum class. Disadvantages: this class is unintuitive to use, since enum consumers must instantiate enum values. Also, it's needlessly crufty—enum definitions still assign integers to each enum!
 * Use an existing implementation. This is a possibility, though there doesn't seem to be any agreed-upon standard.
 * Build something better ourselves. Hopefully the proposed implementation, described below, fits the bill.

Current functionality
With the proposed implementation, you can define some enums like this:

The call to  can go in the same .php file as the enum definition. It assigns unique values to the static properties and sets up an index for helper functions. It must be performed before the enum is used.

Once you've defined your enums and called, here's what you can do:

There's also an interface,, which you can extend. For example:

Extensibility
In the current implementation, it's already possible to add custom methods and properties to enum classes. If use cases arose, it would be easy to add custom constructors and constructor calls. (Just like in Java! See, for example, this tutorial.)

Tests
The implementation includes unit tests.

Advantages

 * Compact
 * Intuitive
 * Typesafe
 * No need to declare or see meaningless integer values
 * Meaningful conversion to strings
 * Helper functions on sets of enum values
 * Extensible
 * IDE autocompletion works

Disadvantages

 * You have to add a  before the enum names.
 * The enums look like constants, but they aren't really constants. Though it's unlikely, the values could be changed by accident.
 * must be called on each enum class before it can be used. The above suggestion that it be called in the same .php file as the enum definition appears to violate Section 2.3 of PSR-1. (However, it may not violate the spirit of that standard—see the talk page for further discussion.)

Alternate approach
Another common approach to enums emulation in PHP is to use methods. Here is how enums might be defined and used following that approach:

Advantages

 * Compact
 * Typesafe
 * No need to declare or see meaningless integer values
 * Meaningful conversion to strings
 * Helper functions on sets of enum values
 * Extensible
 * No need to call  or transgress PSR-1
 * Values can't be changed by accident

Disadvantages

 * Less intuitive: you have to think of EnumClass::THIS as a constant rather than a function
 * No IDE autocompletion

Use cases
Current work in progress on Editor campaigns uses the proposed implementation quite a bit.

For more possible use cases, just go to the core or mediawiki-extensions directories say.