Grouping of constants

Published on and tagged with php

Almost every application uses some constants, and sometimes you have groups of related constants. And so the question arises: “How can I group those constants?”. The easiest way is to use a prefix as shown in the following example:

define('OAUTH_REQUEST', 'http://oauth.net/core/1.0/endpoint/request');
define('OAUTH_AUTHORIZE', 'http://oauth.net/core/1.0/endpoint/authorize');
define('OAUTH_ACCESS', 'http://oauth.net/core/1.0/endpoint/access');

These constants build the (implicit) group “OAUTH”. With the old PHP 4 that’s all you can do, with PHP 5 it is also possible to create explicit groups by using class constants. So we can refactor the example from above to:

class OauthConstants {
    const REQUEST = 'http://oauth.net/core/1.0/endpoint/request';
    const AUTHORIZE = 'http://oauth.net/core/1.0/endpoint/authorize';
    const ACCESS = 'http://oauth.net/core/1.0/endpoint/access';
}

The group name is now the name of the class, and we can access those constants with ClassName::CONSTANT_NAME (e.g. OauthConstants::REQUEST).

Even though this approach is a bit limited (for example, you can’t use string concatenation, see also Class Constants) and there is no convention on where to place such classes in CakePHP, it is a handy way to organize your constants.

16 comments baked

  • Christian Winther

    I would call the class for Oauth – no need for a class with only constants :)

  • José Lorenzo

    Why don’t you use Configure::write() and read()? …I think is better than using constants, and a little more semantic

  • Nik

    I think it’s a nice approach, but I also started using Configure class for storing constants.

  • ajmacaro

    @jose
    If you can edit it. then it wasnt a CONSTANT anymore.
    and yes i used approach #1.
    but the real question that i want answer is how fast it is?

  • David Persson

    It would be nice though if it was possible to use the Configure class for creating constant vars. I don’t know if it is technically possible to create class constants on the fly (sure it is) so those vars can only be written once.

    I’m personally using normal constants for declaring paths and for all the other stuff the Configure class (best of both worlds).

  • David Persson

    Just did a quick benchmark on reading scalar values from constants, class constants and the configure class:

    1000000 iterations

    0.000149384320259 ms (Read with Configure)
    0.000008934016466 ms (Read from Constants)
    0.000009548342705 ms (Read from Class Constants)

    The code I used for testing can be found here:
    http://bin.cakephp.org/view/2134645478

    One has to keep in mind that the Configure class is also capable of storing non scalar values as well. Please run the test yourself to ensure the results a valid.

  • David Persson

    Sorry I’m very bad in making benchmarks…

    Each result is the *average* time in *seconds* it requires to read 3 values.

    My environment is:
    PHP: PHP 5.2.6-pl6-gentoo
    OS: Linux 2.6.25-gentoo-r7
    CPU: i686 Intel(R) Celeron(R) M processor 1.50GHz GenuineIntel
    MemTotal: 904140 kB
    CakePHP: 1.2.0.7692 RC3

  • cakebaker

    @all: Thanks for your comments!

    @Christian: Well, it depends on the situation ;-) If you have multiple classes using the same constants, to which class do you add those constants? On the other hand, if the constants are used by only one class it makes sense to add them to that class.

    @José: The Configure class is great to store configuration data. But for “real” constants, i.e. values you cannot change, I prefer to use the respective language construct, hence the use of “const”.

    @ajmacaro: See David’s comment, it seems like class constants are slightly slower than “normal” constants.

    @David: Hm, I don’t see why you would want to use the Configure class to create class constants. To me it seems like an unnecessary indirection ;-)

    And thanks for your benchmark!

  • Juan Basso

    If have multiples classes, maybe a class for constants is great. But if a define is for some configuration or something like this, is great use Configure class.

    In benchmark 3 reads is 0.00013 seconds slower than class. 0.00004 slower than class is acceptable to make a configuration with Configure class and in cake’s style.

  • dr. Hannibal Lecter

    I have used this system in multiple projects (at work and home), and it is much more logical/descriptive than the regular defines.

    Recommended!

  • cakebaker

    @Juan, Hannibal Lecter: Thanks for your comments!

    @Juan: I didn’t mean you should always use this approach ;-) It really depends on your use case, sometimes it makes sense, sometimes it is better to use “define”s or the Configure class. To find the right approach, you have to know the possible approaches…

  • charlie

    And what about settings? things you want the admins be able to change without having to go to the source code and change it there.

    Should this be made in the database? I’ve seen CMS like WordPress and Drupal store settings in a table, so there’s a whole table for just one record with the settings which seems like it’s too much. Is that the best practice for settings?

  • cakebaker

    @charlie: Thanks for your comment!

    I don’t know if it is a best practice, but it is the solution you get if you model a configuration file as an object.

    A different approach is to see the configuration as a data container storing key/value pairs, so there is a record for each setting in the table.

    In the end it depends on the situation (and your preferences). The first approach is better suited if there are only few settings, whereas the second approach is better if you have many configuration settings.

    Hope that helps!

  • rafaelbandeira3

    Nice idea. As of php 5.3 one can use namespaces too – but be aware that it’s still an experimental extension

  • cakebaker

    @Rafael: Yes, that’s an option which will become interesting in the future. But as you say, it is currently experimental stuff…

  • Grouping “constants” with JavaScript - cakebaker

    […] while ago I wrote about how you can group related constants in PHP5 by using a constants […]

Bake a comment




(for code please use <code>...</code> [no escaping necessary])

© daniel hofstetter. Licensed under a Creative Commons License