PHP Pandas: Constants

← Back to Index

In a previous chapter, we discovered variables, and how they could be used to store a variety of different types of information. You could re-assign a variable to a new value, and PHP wouldn't give two hoots about it!

Sometimes, things aren't meant to change. Old people will always prefer to wear beige. The government will continually attempt to throw your money away. Red pandas will consistently become excitable in periods of cold weather.

Defined Constants

There are values in your code that might not want to change too. For example, let's use that wibbly-wobbly time fading technique they use on TV shows to go back in time and take another look at the assignment of the $pi variable.

$pi = 3.14159265359;

There she is. Beautiful.

Do you think that the value for PI is ever going to change? I mean sure, it can always be calculated to additional decimal places by clever white coat wearing boffins, but is it likely to need to change within our program?

I doubt it. In fact, if someone was to do this...

$pi = 5;

... then our circumference calculations would be in big trouble. We'd have our middle school Math professor frowning at us, and we don't want that.

It would be great if we could lock our $pi variable to a value, so that it couldn't be changed at all. Well, as it turns out, a variable isn't what we need at all. We need something called a constant.

Constants used outside of classes (I like to call this the Global scope.) are defined using a special function. Let's take a look.

define('PI', 3.14159265359);

We use the define() function to set our PI constant to the correct value. As you can see, the constant name is the first parameter to the function, and its value is the second.

You'll notice that the constant name is written in uppercase. This isn't only true for the PI constant. A convention for programmers is to write constants in uppercase, and use underscores for spaces. THIS_IS_A_CONSTANT.

Let's try to use our constant. It's very similar to a variable, only that it doesn't begin with a $ dollar sign. Let's attempt to echo our constant.

// Define our constant.
define('PI', 3.14159265359);

// Echo the value of PI.
echo PI;

Executing our snippet of code yields the result:

3.14159265359

Great! This is exactly what we'd get using a variable. Let's now try to re-define the constant. For example:

// Define our constant.
define('PI', 3.14159265359);

// Re-define our constant.
define('PI', 42);

What do you think will happen when we try to execute our code? Let's give it a go.

Notice: Constant PI already defined in <file> on line <number>

A notice! It's telling us that we've already defined PI, and that we can't change its value. The notice won't break our code, but it will protect us from accidentally changing the value of the constant. Our circumference calculations are safe.

The naming limitations of constants are identical to those of variables, and you can define as many constants as you need. Constants are best described as 'immutable', and will not be changed.

Class Constants

The constants defined in the previous section are considered 'global', and are accessible by all parts of our application. Sometimes, we only need constants that are to be used by our classes.

For example, let's make a simple circle class.

<?php

class Circle
{
    /**
     * The value of PI.
     *
     * @var float
     */
    private $pi = 3.14159265359;

    /**
     * Calculate the circumference of a circle from diameter.
     *
     * @param  mixed $diameter
     * @return mixed
     */
    public function circumference($diameter)
    {
        return $diameter * $this->pi;
    }
}

Our circle class has a private property called $pi, which contains the appropriate float value. It also has a public method called circumference(), which takes a diameter of the circle as a parameter to calculate its circumference.

Let's test this class.

$circle = new Circle;

echo $circle->circumference(32);

Executing the above code snippet yields us the value 100.53096491488, which is not only my jeans size, but also the correct circumference for our circle. However, while we know that the private variable cannot be changed outside the class, it can still be changed from within.

<?php

class Circle
{
    /**
     * The value of PI.
     *
     * @var float
     */
    private $pi = 3.14159265359;

    /**
     * Calculate the circumference of a circle from diameter.
     *
     * @param  mixed $diameter
     * @return mixed
     */
    public function circumference($diameter)
    {
        $this->pi = 48;
        return $diameter * $this->pi;
    }
}

This time our value would be incorrect, due to the re-assignment of the $pi class property. It may seem an unlikely change, but within a large class with many functions, the risk of change increases dramatically.

We like PI. Especially cherry pie. We don't want it to change. Let's make it a class constant instead.

Within classes, constants can be defined using the const keyword. Let's take a look at an example.

<?php

class Circle
{
    /**
     * The value of PI.
     */
    const PI = 3.14159265359;

    /**
     * Calculate the circumference of a circle from diameter.
     *
     * @param  mixed $diameter
     * @return mixed
     */
    public function circumference($diameter)
    {
        return $diameter * self::PI;
    }
}

We've used the const keyword to define our PI class constant, and have given it a value.

const PI = 3.14159265359;

The value of PI is now immutable, and PHP will throw an error if you attempt to change it. Now, you can't use $this to access a class constant, and I'll explain why shortly. For now, you'll need to trust me, and instead use the self keyword, followed by the double :: colon operator, and finally the constant name. Like this:

return $diameter * self::PI;

Simple! Now our value for PI can be used, but will never change. But what's this self:: stuff all about?

Well, you may have noticed that the constant we created did not include any scope (public/private/protected/static). Our constant cannot be changed, and because of this, its value will be the same across all instances of our Circle class.

For this reason, constants are not accessed in the same manner as class properties. In fact, you don't even need a class instance to access the constant. Confused? Take a look at the following piece of code, which makes use of our Circle class.

echo Circle::PI;

If we execute the snippet above, we'll receive the correct value for PI. We don't need a class instance. Using the double :: colon operator, we can access the PI constant directly on the class definition. This means that class constants can be considered somewhat public, since their values can be accessed (but never modified!) from outside of a class instance.

The double :: colon operator is actually known as the Scope Resolution Operator, or even the Paamayim Nekudotayim. Both of these sound terrifying, so let's stick with double colon for now.

It's worth noting that we can access the constant in a similar fashion from a class instance. For example, the following code is entirely valid, and yields an identical result to the previous example.

$circle = new Circle;

echo $circle::PI;

Within the class, self is used as a reference to the current class definition. On the following line...

return $diameter * self::PI;

... we could have also accessed the PI constant using the class definition itself...

return $diameter * Circle::PI;

... and the code would execute as expected.

However, if we later decide to rename the Circle class, we'd also have to replace all constant accessors within the class to match. For this reason, using self to address the current class definition is far more convenient.

When defining variables, always take a moment to think about their purpose, and whether their value is needed/likely to change. Use constants where appropriate to protect the functionality of your code.

My books are available online for free to encourage learning. However, if you'd like for me to keep writing, then please consider buying a digital copy over at Leanpub.com.

It's available in PDF, ePub, and Kindle format, and contains a bunch of extras that you won't find on the site. I have a full-time job, and I write my books in my spare time. Please consider buying a copy so that I can continue to write new books from the comfort of my sofa!