All About the 'Static' Keyword

Today we are going to learn how to use the 'static' keyword in PHP. We are going go over the basics and build some examples. It is time to add this interesting language feature to your web development bag of tricks.

1 A Quick Example

Let's stay with a quick example first, to see the effect of using the static keyword.

Imagine writing a function that remembers how many times total it has been called. If you are not familiar with the 'static' keyword, you may resort to using some global variable:

Just because this works does not mean you should write code this way. Generally speaking, global variables are frowned upon. It's not a good idea to have global variables floating around, that some function only utilize privately.

Same result, no more global variables. But how does this work exactly?

Normally, all local variables inside of a function get destroyed once the function returns. The 'static' keywords lets PHP know to keep the variable alive. So, the next time the function is called, the value inside the variable is retained.

2 Valid Initial Values

As seen the previous example, when we assigned the value of 0 to the variable, it actually did not execute an assignment statement. It only set the initial value for the variable. That may sound like the same thing, but there is a slight difference. The variable can only be initialized to a fixed value, and not an expression.

Let's see some examples of valid and invalid initial values. First, let's look at numbers:

If the data was coming from a database, and the table rows were output within a loop, you would need to add some code to be able to set those alternating CSS classes to each row. Most people would just go ahead and create a variable within that loop, add a conditional or ternary statement to keep alternating its value.

However, we are going to build a more elegant and reusable solution. We are going to create a function named alternate() that utilizes the concept of static variables.

We call the function with two arguments. Every time it is called, it returns back one of the arguments in an alternating fashion. It accomplishes this by keeping a boolean value in a static variable called $alt. Every time it flips this variables value, to determine which one of the two arguments to return.

4 Improving Our Alternate() Function

The function we created works well, if we use it only in one spot in our scripts. There is a small problem with it, however. If we use it in multiple places, or in nested loops, it may not return the values in the order we intended. Let's look this code to demonstrate this issue:

Our function needs to be aware that it is being called from different places, and make sure to return the values accordingly. We can accomplish this by adding an optional last parameter, to assign an ID number. And we pass a unique ID from each different place we call it from, to avoid these conflicts:

This time we are utilizing an array as a static variable. It will carry a unique boolean value for each different ID number that was passed. This allows it to return the values in correct order.

5 Static Class Members

The 'static' keyword is not only used inside functions. It is actually quite common in object oriented programming. There can be static members, and methods. First we are going to look at how static members work.

Note how we used the 'self::' keyword in front of the static variable for accessing it within the class, rather than '$this'. Also, when used in the outer scope, we do not need to create an instance of the object before we can access the static variables. However, normal class members can only be accessed after we created an instance of them.

6 A Class That Counts Itself

Remember our first example where we had a function that kept a count on how many times it was called? Now let's apply the same principle to object oriented programming.

This class will have the ability to count how many times total it has been created:

Every time a new object is created, the constructor function is called by default. This function contains code for setting the counter and the id number for that instance of the object. So, if an object was created for the third time, that object will have an id of 3, which is specific only to that object. The counter will keep going up as more objects keep getting created.

Note that regular class members exist separately on each object. However, the static members only exist once globally.

This is the skeleton structure. You can of course add more methods and member, or simply extend the class.

When we call the getInstance() method, two things happen.

$var = Foo::getInstance();

First, if there is no Foo object, one is created and assigned to Foo::$instance. Then, once there is that object, it is returned, so $var becomes that object. If you call it multiple times, every time you will get the same exact object; a new instance will not be created.

We have one method for fetching a user by id from the database. So it could be used like this:

$user = new User();
$user->load_user($user_id);
// now I can see the name, and other things
echo $user->name;
echo $user->comment_count();

Now imagine that once a user is logged in, you store their id in the session. And next time they load a page, you need to look up that id, and create the related $user object for that user again, if you wish to access the members and methods of that object.

But due to variable scope issues, you will either need to make the $user object global, or keep initializing it from different functions/methods within your script. Here is where a singleton class can come in handy:

So, in our code we did not need to worry about dealing with session. We can simply attempt to get the instance of the CurrentUser object and use it just like any User object, as it extends its functionality.

Conclusion

I hope you enjoyed this tutorial and learned from it. See you next time!

Burak Guzel is a full time PHP Web Developer living in Arizona, originally from Istanbul, Turkey. He has a bachelors degree in Computer Science and Engineering from The Ohio State University. He has over 8 years of experience with PHP and MySQL. You can read more of his articles on his website at PHPandStuff.com and follow him on Twitter here.