PHP Constants: How many is too many?

PHP ConstantsWhat are PHP constants?

A constant allows you to define data that will not change during execution. Think of it like a variable that is always the same. This may not sound very useful at first but I am going to show you how PHP constants can improve performance, reduce bugs, and help you to keep your code organized.

To understand constants fully it is important to also understand variables and literals. A variable is simply a name meant to symbolize a value. The name stays the same although the value might change. A literal is the value itself when used without a variable. In for($i=0;$i<10000,++$i){ the variable is $iand the literals are 1 and 10000.

Can constants really improve performance?

The answer depends on what you were using before constants. If you use a constant to replace a variable then it will improve performance. The improvement can add up quickly if you are replacing variables that don’t change throughout your code. For example see the code below and consider how a constant could improve it.

$url = 'www.schaefersoftware.com';

header('location: '.$url);

Notice that the url “variable” is declared and then immediately used once and never changed. The following code contains a constant instead of the variable.

define('URL', 'www.schaefersoftware.com');

header('location: '.URL);

This is faster because the constant is replaced with a literal before execution and no space is allocated for the variable, as it was before. See the following example using a literal only.

header('location: www.schaefersoftware.com');

This may be the fastest way to write this code since no extra work is needed to get the url in place and the concatenation can be skipped as well. The performance advantage offers a compelling reason to stop using variables where constants can be used. However, literals are sometimes faster than constants.

I ran some tests using my Profiler and got some interesting results. To set up the test I added profiler checkpoints between 3 loops. The first loop concatenated 3 literals, the second concatenated 3 constants, and the third concatenated 3 variables. I set each loop to run 1,000,000 times to give us a nice average result. I found that the constants and the literals consistently took almost exactly the same amount of time and the variables consistently took up to 4 times longer to run. Why is it that the constants took no more time than the literals? This is because by the time execution begins the constants have already been replaced with literals. In a way this is a limitation of our profiler, because it runs inside the PHP application and doesn’t profile before execution when the constant is replaced.

Why should I use constants if literals are just as fast?

img_3320It is appropriate to use constants to replace literals in many cases. Constants are a great organizational tool for improving maintainability and reducing bugs. Assume you are building a large system that handles data from the user with HTML forms. You probably have the code to display the form separate from the code to process the data when the form is submitted. Whether it is separate or not you still need the name attribute from an input on your form to match the name you are looking for in your $_POST or $_GET superglobal. To accomplish this you can simply write a literal name="name" attribute in the input and look for $_POST['name'] after the form is submitted but this can lead to mistakes. For example, if the form is a user interface allowing the user to input their name, email address, and other personal details, you might have several of these forms that all submit to the same place. Perhaps one form is displayed when the user first signs up on your website, and another is used for a ‘My Account’ page, and yet another for your administrative tools. If you change the input name attribute to ‘first_name’ you will need to make sure that you find every place you were using it before and change it there too. A constant can take this burden away. If you have a user class you could define a constant like const INPUT_NAME = 'name';

Notice that I used const instead of define(). Use the keyword const when you are declaring a constant within a class, and use define outside of a class when you need a constant to be available everywhere. As of PHP 5.3 you may also use the keyword const outside of a class.

Once this constant is defined you can create your input with $input = '<input type="text" name="'.User::INPUT_NAME.'" value="">';

To capture the value of the input you need to get the value of $_POST[User::INPUT_NAME]

 

It’s that simple. If you think about using a constant every time you are writing a literal you will find that you can use them very frequently. When you have to change something you will be glad that you used a constant since you can go to the constant definition and change it there, instead of changing it all over your program.

This is a more organized way to do things, in which you can create configuration files containing constants for system settings that will largely stay the same but may change in the future. You can also tie constants to objects as in the example above. This makes your code easier to read and quicker to write, especially if you have a good IDE with autocomplete.

Constants can make your database smaller

As an added bonus you can use constants to reduce the size of your database. Consider the user class from before. Let’s assume that you store a status for each user as either Active, Inactive, Disabled, or Deleted. You might just write these strings into a varchar field in the database but with constants we can store them in a tinyint. To represent these in your user class you would do the following.

const STATUS_ACTIVE = 0;
const STATUS_INACTIVE = 1;
const STATUS_DISABLED = 2;
const STATUS_DELETED = 3;

Now you can store these values in the database and refer to them wherever you use the status in your code. In effect PHP will always see those numbers and will not care what they are named, but the human readable version in the code will use the name of the constant. If you want to display the names through PHP it is nice to create a status map.

static $status_map = array(
 self::STATUS_ACTIVE=>'Active',
 self::STATUS_INACTIVE=>'Inactive',
 self::STATUS_DISABLED=>'Disabled',
 self::STATUS_DELETED=>'Deleted',
);

Now you can get printable text to display the status with $display_status = User::$status_map[$user->get_status()];

This assumes that you have a get status function that will simply return the status value, which in our case will be 0, 1, 2, or 3.

Now if you are writing a new feature that requires you to set the user’s status, you can let your IDE tell you what statuses are available be typing out User::STATUS_ and seeing what options it gives you with autocomplete.

So to answer the question “How many is too many?”, I would argue that no amount of constants is too many. There isn’t a significant downside to using them, but there are plenty of benefits.

Leave a Reply

Your email address will not be published. Required fields are marked *