Pseudo-ENUM in PHP

I’ve been working on a project lately where I’m rolling my own basic role-based access control (RBAC) system. In experimenting with different ways to handle the role definitions, I though that it’d be nice to have a basic enum() function or construct, as a quick, convenient way to define a set of constants. There’s this option:

<?php
    define('ADMIN',     0);
    define('MODERATOR', 1);
    define('EDITOR',    2);

but that isn’t exactly succinct. I’d rather have something like this:

<?php
    enum('ADMIN', 'MODERATOR', 'EDITOR');
    // ADMIN == 0 
    // MODERATOR == 1 
    // etc.


Of course, that won’t work. enum() doesn’t exist in PHP. You can kind of mimic the enumerated values with arrays like so:

<?php
    $roles = array(
        'ADMIN'     => 0,
        'MODERATOR' => 1,
        'EDITOR'    => 2,
    );

but having to specify those values is tedious. There’s an easy trick to get around that though:

<?php
    $roles = array(
        'ADMIN',
        'MODERATOR',
        'EDITOR',
    );

    /*
    Array
    (
        [0] => 'ADMIN'
        [1] => 'MODERATOR'
        [2] => 'EDITOR'
    )
    */
 
    $roles = array_flip($roles);
 
    /*
    Array
    (
        [ADMIN]     => 0
        [EDITOR]    => 1
        [MODERATOR] => 2
    )
    */
 

Which is cool! But not cool enough, because I want constants, not just array values. Which is cleaner?

if ($role == $roles['ADMIN']) // ew  :(
if ($role == ADMIN)           // ahh :)

So a bit more digging, and I found that APC can turn an array into a bunch of constants in one fell swoop!

<?php
    /**
     * Try loading the constants from APC
     */
    if (!apc_load_constants('roles'))
    {
        /**
         * they aren't in APC, so make 'em and define 'em
         */
        $roles = array_flip(array(
            'ADMIN',
            'EDITOR',
            'MODERATOR'
        ));
 
        apc_define_constants('roles', $roles);
    }
 
    /**
     * Now we've got enumerated constants!
     *  ADMIN     == 0
     *  MODERATOR == 1
     *  EDITOR    == 2
     */

Obviously you need APC to make this work. One great thing about using apc_load_constants() is that you might get a modest speed boost because you don’t have to define() all of your constants every time the script runs. Another benefit is that you can load up your array of roles (or whatever your constants are, e.g., permissions, etc.) from a database or other dynamic source, and convert them into global constants with one function call.

Now what would be even cooler is if you could tell apc_load_constants() to load the constants into a specific namespace, maybe something like:

<?php
    apc_load_constants('roles', true, 'drew');
 
    echo "ADMIN's value: " . drew::ADMIN;

How cool would that be? Though that kind of namespace madness will need to wait until PHP 5.3 I assume.