Converting PHP defined constant values to multiple languages We have a large number of defined constants that are used as enum values when storing records. We convert the int values into language for our web portals. This was very straightforward when only dealing with one language, but now are tasked with making the portals support multiple languages.

The functions doing the value to language are easy enough to change and I have a solution, but I was wondering if there wasn't a better way as what I've come up with involves a little too much copy/paste for my taste. What I can't change are how we define the constants/enums.

The language files are written in json as key/value pairs. Language::_($key) handles looking up the proper language files and returning the string. 

Another thought I had was to do the lookup based off the constant's value, but I couldn't find a way to pass constant's name (ACTION_ACCOUNT_NEW) to Language::_($key); I believe constants are evaluated before execution. I also don't want to pass the constant's value (1024) to Language::_($key) as I believe that would make a json file that would be very difficult to read.

Would there be a better way of doing this that involves less cut/paste of the defined constant names?

define('ACTION_ACCOUNT_NEW', 1024);
define('ACTION_ACCOUNT_DELETE', 1025);

function ActionToString($action){

    $actions_map = array(
        ACTION_ACCOUNT_NEW =&gt; Language::_('ACTION_ACCOUNT_NEW'),
        ACTION_ACCOUNT_DELETE =&gt; Language::_('ACTION_ACCOUNT_DELETE')
    );

    return isset($actions_map[$action])
        ? $actions_map[$action]
        : Language::_('Unknown');
}


json

{
    "ACTION_ACCOUNT_NEW": "Account Created",
    "ACTION_ACCOUNT_DELETE": "Account Deleted",

    "Unknown": "Unknown"
}
In all honesty, that seems a bit redundant... But since you can't change the constant values here it goes:

define('ACTION_ACCOUNT_NEW', 1024);
define('ACTION_ACCOUNT_DELETE', 1025);

function ActionToString($action)
{
    $actions_map = array();
    $defined_constants = get_defined_constants(true); // use true to get "user" key

    if (isset($defined_constants['user']))
    {
        $defined_constants = $defined_constants['user'];

        // only process constants that start with "ACTION_"
        $defined_constants = array_intersect_key($defined_constants, array_flip(preg_grep('~^ACTION_~i', array_keys($defined_constants))));

        foreach ($defined_constants as $key =&gt; $value)
        {
            $actions_map[$value] = Language::_($key);
        }

        return isset($actions_map[$action]) ? $actions_map[$action] : Language::_('Unknown');
    }

    return Language::_('Unknown');
}


It assumes you only want to parse constants that start with ACTION_, other than that it should work just fine (although, a bit slower due to the looping - still, you could probably fix it with static variables).

One other alternative would be to use class constants but I'm not sure if that option is available to you.