Question

Lately I've been in the habit of assigning integer values to constants and simply using the constant name as a means of identifying its purpose. However, in some cases this has resulted in the need to write a function like typeToString($const) when a string representation is needed. Obviously this is inefficient and unneccesary, but is only an issue every once and a while.

So my question is, are there any other tradeoffs I should consider? Which case is considered to be cleaner/more standards-compliant? Also, is the performance difference negligable for most cases?

Case 1: (faster when a string version is not needed?)

class Foo {
    const USER_TYPE_ADMIN = 0;
    const USER_TYPE_USER = 1;
    const USER_TYPE_GUEST = 2;

    public $userType = self::USER_TYPE_ADMIN;

    public function __construct($type) {
        $this->userType = $type;
    }

    public function typeToString() {
        switch($this->userType) {
            case self::USER_TYPE_ADMIN:
                return 'admin';
                break;

            case self::USER_TYPE_USER:
                return 'user';
                break;

            case self::USER_TYPE_GUEST:
                return 'guest';
                break;

            default:
                return 'unknown';
                break;
        }
    }
}

$foo = new Foo(Foo::USER_TYPE_GUEST);
echo $foo->typeToString();
// Displays "guest"

Case 2:(faster/easier when a string version is needed)

class Foo {
    const USER_TYPE_ADMIN = 'admin';
    const USER_TYPE_USER = 'user';
    const USER_TYPE_GUEST = 'guest';

    public $userType = self::USER_TYPE_ADMIN;

    public function __construct($type) {
        $this->userType = $type;
    }
}

$foo = new Foo(Foo::USER_TYPE_GUEST);
echo $foo->userType();
// Displays "guest"
Was it helpful?

Solution

The performance difference will be negligible unless you're storing a lot of them. I'd write the toString() method more concisely:

$strings = array
(
    self::USER_TYPE_ADMIN => 'admin',
    self::USER_TYPE_USER => 'user',
);

if (!isset($strings[$type]))
    return 'unknown';

return $strings[$type];

Also, you could make the $strings array a static.

OTHER TIPS

I'll be honest, I don't know if there's a performance "hit" of any kind when you define your constants natively as strings - but if there is one at all I'm willing to bet that it's so small it would be difficult to measure.

Personally, if the constant's value is meaningful as a literal, then just assign it that value. If the constant's value is meaningful only as an option selector (or some other indication of value), then use integers or whatever you choose appropriate.

I think string constants are the best choice in this case. Code looks better.

Of course if you need last bit of performance, use integer constants. But only after you verify with a profiler that string comparisons are the bottleneck. Anyway, in most applications there are many more expensive things, like database access etc.

Instead of using const integers I generally just go with strings if I need to print them. So I'd do something like $foo = new Foo('guest');. I can still validate the input in the constructor and I can mark it up whenever I need it.

In the example you write you could drop all the methods and make the class static and you would have created your self an Enumerator. Like this:

class Enumeration{
  public static const One=1;
  public static const Two=2;
  public static const Three=3;
}

One other handy way to use constants is to use them as application configuration. They are much faster performance wise then parsing an xml file for configuration.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top