#1
  1. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Sep 2006
    Posts
    1,806
    Rep Power
    529

    Define constants versus global variables


    Hi,

    In the beginning of my script, I define a bunch of constants such as paths to a given directory, maximum file sizes, Google map keys, etc. They will never change, and I wish them to be available to all classes, files, etc.

    Would you recommend I define them as a constant, or use a global array? What are the pros and cons of both approaches? As I see it, a pro of using constants is that they can't be inadvertently changed, and a pro of using a global array is that they are all grouped under the same array name.

    Thanks!
  2. #2
  3. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,925
    Rep Power
    1045
    Hi,

    I'd put them into a class as class constants:
    PHP Code:
    class Config {
        const 
    PATH '/a/b/c';
    }

    echo 
    Config::PATH
    This way you have both constant values and grouping.

    A big "bug" in PHP, however, is that constants cannot hold arrays. If you need that, I'd probably fall back to static getter methods.

    Personally, I wouldn't use global variables at all. They're cumbersome to use, and it's not clear if they're supposed to be constant or not (apart from the fact that they're not, of course).
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Sep 2006
    Posts
    1,806
    Rep Power
    529
    Thanks Jacques1. Seems like a great solution.

    I am not really familiar with the static getter methods. Upon Googling the phrase, seems like it relates to overloading classes/objects. This concept is also rather foreign to me. A bit off topic, but do you mine explaining how the two subjects relate so I may better understand the concept? Thanks
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Sep 2006
    Posts
    1,806
    Rep Power
    529
    Also, how would you set a class constant to something like $directory."file.php"?
  8. #5
  9. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,925
    Rep Power
    1045
    With getter methods I mean that you put the config values in private static attributes so that they cannot be accessed directly from outside the class. And then you give "the outside world" read access through (public) methods:

    PHP Code:
    class Config {

        private static 
    $dir '/a/b/c/';

        public static function 
    getDir() {
            return 
    self::$dir;
        }

        public static function 
    getFile() {
            return 
    self::getDir() . 'index.php';
        }

    }

    echo 
    Config::getDir();
    echo 
    Config::getFile(); 
    The idea is to limit access to the variables and make them kind of "pseudo-constant" (though they can still be changed by other methods of the class).

    Comments on this post

    • aeternus agrees : Thanks for sharing!
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Sep 2006
    Posts
    1,806
    Rep Power
    529
    Thank you Jacques1,

    Why not some generic function such as:
    PHP Code:
    public static function getConstant($name) {return self::$name;} 
    Seems a little cumbersome to maintain. Using something like define ('myConst',$a*$b) seems easier, but doesn't give the benefit of grouping. Maybe add a setter function that can only be used once?
  12. #7
  13. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,925
    Rep Power
    1045
    Originally Posted by NotionCommotion
    Why not some generic function such as:
    PHP Code:
    public static function getConstant($name) {return self::$name;} 
    I guess you mean
    PHP Code:
    self::$$name 
    Sure, you can use a general getter. But this has several issues:
    • You'd have to make an explicit lists of all allowed attributes (because you certainly don't want to expose all private attributes)
    • You have to add error handling for invalid attributes
    • It's no longer possible to have "virtual" attributes, which are "calculated on demand"; each attribute has to actually physically exist
    • From the outside, you cannot determine which attributes even exist

    So I'm not sure if saving a few lines is worth the trouble.



    Originally Posted by NotionCommotion
    Seems a little cumbersome to maintain. Using something like define ('myConst',$a*$b) seems easier, but doesn't give the benefit of grouping.
    Well, like I said, you can use class constants. This gives you the grouping. However, constants in general can only hold literal values like strings and numbers, not arrays, database connections or something like that.



    Originally Posted by NotionCommotion
    Maybe add a setter function that can only be used once?
    No, that's too obscure. Keep it simple and intuitive.

    If you neither like getters nor (class) constants, another option would be to use an external configuration file (JSON, YAML, XML or whatever). This has the benefit of only containing data without any PHP overhead. However, you won't be able to concatenate values or do any "calculations".

    So as you can see, each approach has advantages and disadvantages. Choose the one that fits your concrete application best:
    • class constants: little overhead, but only literal values
    • private attributes with getters: some overhead, but you can use any value
    • external configuration file: no overhead at all, but only constant values

    If you only deal with simple things like "PATH = $dir . 'index.php'", use class constants. If you want to store complex values (including arrays), use getters.
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Sep 2006
    Posts
    1,806
    Rep Power
    529
    Thanks again Jacques1!!!

    Seems like a complicated subject, and I appreciate your recommendations, and your pros and cons to each option. Looks like I will need to sleep on this one!

    Michael
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Sep 2006
    Posts
    1,806
    Rep Power
    529
    If you only deal with simple things like "PATH = $dir . 'index.php'", use class constants.
    I am under the impression that this is not possible. Am I mistaken?

    Comments on this post

    • Jacques1 agrees : My bad.
  18. #10
  19. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,925
    Rep Power
    1045
    You're right, sorry. Class constants are even more restrictive than global constants.
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".

IMN logo majestic logo threadwatch logo seochat tools logo