3

Basically, I develop websites, some large with many crud operations, etc...

However I've gotten into the habit of storing re-usable data as a constant in my PHP applications

I currently have 44 constants defined in one application.

These range from:

  • Database config
  • Home page for admin and guest
  • url slug names
  • declaring development mode
  • declaring maintenance mode
  • a few directory shortcuts ( instead of writing /admin/templates/images ill use const ADM_IMAGES )
  • session names
  • cookie names
  • random things like MAX_IMAGE_SIZE, THUMB_SIZE and MAX_LOGIN_ATTEMPTS

I don't have any problems using all these constants... It's kind of helpful having all these in my application.

I just wanted to know if its a 'good practise' to use them in this excess

If not, how else could this data be encapsulated to be useful AND easy enough to reach in my application? Also bearing readability in mind.

7
  • My opinion is one is too many but that's coming from the C# .NET world. I've only done a little PHP, and that mostly in the context of WordPress, but if it's like Classic ASP and VB6, using a few globals might be unavoidable.
    – jfrankcarr
    Commented Aug 21, 2012 at 11:36
  • @jfrankcarr By the way, statics and singleton are also globals (constants or variables, depending on mutability).
    – user7043
    Commented Aug 21, 2012 at 11:39
  • Rather than constants, are many of these config items? Put them in a config file.
    – Paul
    Commented Aug 21, 2012 at 14:11
  • @delnan - I was restricting my comment to only mutable global variables, not constants, statics or singletons (although they can get out of hand too). When you've been handed a legacy VB6 program to maintain with 100's of global variables scattered across several modules, it makes you very leery of them.
    – jfrankcarr
    Commented Aug 21, 2012 at 14:35
  • 2
    @jfrankcarr And how is global mutable state dressed up as singleton or with a dot and a class name in the variable name than global state that is accessed by a plain old variable name?
    – user7043
    Commented Aug 21, 2012 at 14:38

3 Answers 3

14

It's okay to break programming rules if you understand the potential problems the rules are designed to avoid. For global constants, the main problems are discoverability, name clashes, difficulty unit testing, and difficulty recognizing poor cohesion. I would seriously consider refactoring them out in the following circumstances:

  • You are constantly hunting around trying to find either where an existing constant is defined, or where a new one should be.
  • You find yourself making names like HOME1, HOME2, etc. because the name you wanted is already taken.
  • The example is causing a less experienced colleague to use globals where they are neither helpful nor more readable.
  • You are wanting write unit tests that need to change those constants.
  • Feature requests or bugs frequently require changing several files.

To take them out, you have a couple options:

  • Limit the scope of a constant to a single file instead of the entire application. If this is difficult to do, it probably means your code is not cohesive enough and needs refactoring.

  • Make an object or objects that you pass to functions that need it. This takes some practice to define a hierarchy that works.

2
  • 1
    The first sentence is golden :) Commented Aug 21, 2012 at 14:15
  • I like the first option listed a lot. If you neatly organize all those constants into a config file you'll dramatically simplify their understanding and management for new users.
    – Drew
    Commented Aug 28, 2012 at 0:58
8

Having many constants in an application is not a problem for itself - having them all in the global namespace may become one when your application gets larger. So if you have 44 constants, you may consider to group them into classes or namespaces.

Another thing to consider is if it is a good idea to have all those constants beeing part of your program. Separating some of them into a config file allows you to hand over the maintenance of these values to another person (for example, an admin of your customer). So you can more easily deploy a new release of your application to your customer with a smaller risk that those customized values get accidentally overwritten.

5

In general, globals are discouraged. But some things are really "global" in the sense that a single value or setting needs to be shared by many different pieces of code. Sometimes, as Karl points out, sharing data between different areas of your application can mean that your application is structured poorly. If you have 26 source files (named A-Z for simplicity) and 10 globals and 5 of those "globals" are used only by files C, H, and N, then you may want to look at C, H, and N to see what else they have in common and see if it makes sense to merge C, H, and N and make half of your former globals private.

On the other hand, some information may be truly global, like "application-name" or "is-whole-app-in-special-testing-mode." These things may be used in most files of your application. Some tests for good globals are:

  • Is the value immutable once it is set (good) or do you have to worry about one part of your application changing it at runtime and another part getting the old value by mistake (bad)?

  • Is it truly global - a single value that needs to be used by several different independent sections of your application? Obviously you want to eliminate unnecessary dependencies, but some dependencies are necessary.

  • Don't be an idiot. I've heard stories of people making "currently-logged-in-user" a global, thus limiting that web application to a single logged-in user. This kind of global is too stupid to be called evil, but it happens.

For example, when you say "session names" that could mean two things:

GOOD Global:
// Key used to look up number of items in individual user's shopping cart
// Each user's session has a hashtable of values and this is better than
// hard-coding the "numCartItems" string each time you use it because
// the compiler will catch a typo in the NUM_CART_ITEMS symbol, but not
// in a string:
String NUM_CART_ITEMS = "numCartItems";

BAD Global:
// Stores number of items in individual user's shopping cart
// but puts everyone's items in the same cart - OOPS!
int NUM_CART_ITEMS = 0;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.