How Well Do You Understand “Static” Variables?

Today I realized that I did not completely understand the “static” keyword as it applies to variables, which is used in many programming languages. If you weren’t aware of the full breadth of how the static keyword alters a variable, this post should be a mind blower.

So, let’s start simple. Take the following example (it’s in PHP, but you will find EXACTLY the same behavior in ANY language that uses the static keyword on variables – the concept itself is inherited from C):

function test(){
	$test = 0;
	$test += 1;
	return $test;
}

echo test(); //1
echo test(); //1
echo test(); //1

What’s expected, right? Ok, now throw a static in front of the declaration for $test

function test(){
	static $test = 0;
	$test += 1;
	return $test;
}

echo test(); //1
echo test(); //2
echo test(); //3

Trippy, right? When a variable is declared static, it’s stored in the program’s memory for the duration of the program’s runtime (translate for web devs: from the point the static var is created till the request has finished and the page is loaded). In this case, $test is only available within the scope of the test() function, so it isn’t global, but within the scope which it was declared – it persists until the program ends.

Ok, now let’s look at how the same idea applies to classes:

class StaticTest {

	public static $test;

	public function __construct()
	{
		self::$test = 'hello';
	}

	public static function getTest()
	{
		return self::$test;
	}

	public static function setTest()
	{
		self::$test = 'test';
	}

	public function __destruct()
	{
		echo "StaticTest class is dead \n";
	}
}

class Tester {
	public function __construct()
	{
		new StaticTest();
	}

	public function __destruct()
	{
		echo "Tester class is dead \n";
	}
}

new Tester();

echo StaticTest::$test . "\n \n";

The previous example may remind you of the Singleton pattern. The important distinction to be made is that in this example, no instance of StaticTest exists when StaticTest::$test is called at the end of the program. StaticTest is instantiated by Tester, sets a static variable, and then dies. Tester is instantiated, and then dies. The static member of StaticTest itself lives on, and is still available, regardless of whether the class instance which created it is alive or not. Singletons are different because proper Singletons store their static properties privately. Thus, if the Singleton was killed (which, I’ll grant you, presents it’s own set of challenges), it’s members would no longer be accessible, even though they do still exist in memory.

To sum up, a public, static property of a class is generally equivalent to a global property, and thus violates encapsulation. Thus, their implementation within a class interface should be carefully considered. A static variable within a function persists within it’s own scope for the duration of the program’s runtime.

This entry was posted in Abstract, PHP, Programming, Software Design. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

2 Comments

  1. Nick Brown
    Posted February 16, 2012 at 8:41 pm | Permalink

    In the second code example, you should actually put the ‘static’ keyword in there, to be clear about what you mean.


    static $test;
    $test = 0;

    … produces a completely different result than …


    static $test = 0;

    The static keyword not only affects the behaviour of the variable, but also the behaviour of the initialization of the variable, if and only if it is initialzed as part of the static declaration.

    I think you’ll struggle to dispell anyones sense of it being trippy, unless you get that point across.

    Cheers.

  2. Calvin Froedge
    Posted February 16, 2012 at 9:52 pm | Permalink

    Hey Nick, thanks, I dd not include the static keyword in the second code sample by mistake. I copy and pasted from the first.

    You make a great point about what may seem like a subtle difference:

    static $test;
    $test = 0;

    …does yield a totally different result than

    static $test = 0;

    For anyone who may not have caught the difference, in the first example $test is initialized as a static variable with a NULL value, and is then immediately reassigned a value of 0. In Nick’s second example, $test is initialized as a static variable with a n integer value of 0. Because the static keyword is used, $test need not be reinitialized.

    Thanks for reading and contributing!

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>