Static is that pixely-dotty stuff that you get on your television before you tune all your channels in. Right, next chapter. Wait, you're a young handsome/beautiful/both developer aren't you? You're going to be too young to know about tuning terrestrial televisions. Let's take a look at static methods and properties instead then, shall we?
Static Properties
First you're going to need a class.
<?php
class RedPanda
{
}
There she is, bushy tail, fine fluffy coat... what a fine specimen of a class! Normally, we'd have to create an instance of our class to use it, wouldn't we? Something like this...
<?php
$panda = new RedPanda;
As we've learned previously, each instance can contain different values and states to other instances of the RedPanda class. For example, if the class had a name property, one instance might have the name 'Hamish' while another might be called 'Daniel'. The instances of the classes have state.
Well... unless you cheat a little. You see, the class itself can have state. Let's add a static
property to our RedPanda
class, shall we?
<?php
class RedPanda
{
/**
* The panda's name!
*
* @var string
*/
public static $name;
}
By adding the keyword static
after our new property's scope, we've made it static. What does that mean exactly? Well, we can actually use this property without having to create an instance of the class. Here's a simple example...
<?php
RedPanda::$name = 'Hamish';
echo RedPanda::$name;
In the example above, you'll notice that we're not creating an instance of RedPanda. Instead, we're setting the $name
static property using the 'scope resolution operator'... or.. ::
. Don't forget that you still need to use the $
, when pointing out the property. This is a common gotcha, since $this->name
wouldn't require the dollar sign.
Using this method, we can set and retrieve static properties on the class, as if they were public instance properties. That's not all! The instances that we create of this class will also retain the state of that variable across all instances. For example, let's take a look at the following snippet.
<?php
RedPanda::$name = 'Hamish';
$panda = new RedPanda;
echo $panda::$name;
In the example above, we're setting the static parameter to 'Hamish' on the class directly. We then create a new instance of the class, and echo the static property directly from that instance. We receive the result 'Hamish'. No matter whether you are working with the class directly, or an instance of that class, the state of that variable will be common across all circumstances.
Do you think you're limited to only static properties? Oh no! Think again dear reader...
Static Methods
Classes may also have methods that are static. Let's create an example.
<?php
class RedPanda
{
/**
* Make the panda be cute!
*
* @return void
*/
public static function beCute()
{
echo 'The Red Panda rolls around in the snow.';
}
}
Once again, we simply add the keyword static
to the method declaration to make it a static one. Now let's try to use this method on the class itself, rather than an instance of a RedPanda class.
<?php
RedPanda::beCute();
The Red Panda rolls around in the snow.
Aww, isn't that sweet! Because our method is defined as static, we can use it without having to create a class instance.
Now let's setup a trap... no not for the Panda! For ourselves. Consider the following example.
<?php
class RedPanda
{
public $name = 'Hamish';
public static function beCute()
{
$pandaName = $this->name;
echo "{$pandaName} rolls around in the snow.";
}
}
You'll notice that the function is still static, but we've added a class property that is not static. The static method tries to retrieve this property using $this->name
. What do you think will happen when we call RedPanda::beCute()
?
PHP Fatal error: Using $this when not in object context in [file]
Oh dear! Non-static properties belong to instances of classes. They can hold different values in each instances. We're calling our static method on the class itself, so it has no instance to play with. Since there is no instance, $this
resolves to nothing. Any attempts to use it will result in a PHP fatal error.
This also means that we can't call other non-static methods from a static method on a class, because we'd have to use $this->otherMethod()
to do so.
Does that mean that our static methods can't call to other methods? Well not entirely. Our static methods can call to other static methods. Here's an example.
<?php
class RedPanda
{
public static function eat()
{
return self::eatLeaves();
}
private static function eatLeaves()
{
return 'The Panda munches on some tasty leaves.';
}
}
Right, let's run through this. We have a public static method called eat()
, this calls to the eatLeaves()
method and returns the result. Note that the eatLeaves()
method is private, and thus cannot be called directly on the class. It can only be called from within another method of the class.
We're using the self
keyword in the above example. It's used to refer to itself, or the current class. So self::eatLeaves()
means, please make a static call to the eatLeaves()
method of this class.
When we run RedPanda::eat()
we get..
The Panda munches on some tasty leaves.
Many developers use these public static methods to create instances of the classes that they are attached to. For example...
<?php
class RedPanda
{
protected $name;
public function __construct($name = null)
{
$this->name = $name;
}
public static function make()
{
return new self('Hamish');
}
public function getName()
{
return $this->name;
}
}
In the above example, our RedPanda class takes an optional $name
parameter through it's constructor. Then, it sets the $name
protected property to the value you have passed. The public getName()
function can be used to access the name of the panda.
We've also got the make()
public static method, which returns new self()
to create a new instance of the current class, and return it. It even passes 'Hamish' as the name, so we can use RedPanda::make()
to create a new Hamish panda instance quickly.
We mentioned that you can't access instance methods from a static method, but the reverse is perfectly acceptable! For example, you could use
self::staticMethodHere()
from a non-static method and PHP would be perfectly happy.
Late Static Binding
Late static binding is a feature that was introduced in version 5.3 of PHP. It has a really confusing name, so let's demonstrate with code instead. First we need two classes, with a touch of inheritance.
<?php
class Panda
{
public static function whoAmI()
{
return self::getType();
}
public static function getType()
{
return 'I am a Giant panda!';
}
}
class RedPanda extends Panda
{
public static function getType()
{
return 'I am a Red panda!';
}
}
Here we have two classes. Panda is our base class, and represents a giant panda. RedPanda extends from Panda, and represents a red panda... duh. The base class has a static method called 'getType()', which tells you it's a Giant Panda. This method is overridden in the RedPanda class to let you know that it's a RedPanda.
We can use the static whoAmI()
method on both classes to find out what type of panda we have. Let's call it now...
<?php
echo Panda::whoAmI() . PHP_EOL;
echo RedPanda::whoAmI();
Upon running this snippet, we receive the following output.
I am a Giant panda!
I am a Giant panda!
Wait, why are they both Giant pandas!? We've overridden the getType()
method in the RedPanda class, so shouldn't PHP respect the inheritance?
Actually, the self
keyword will only reference the base class. If we wish to use late static binding, we need to replace the self
keyword with static
. Yes, I know... we sure are overusing this keyword. Let's take a look at the transformation.
<?php
class Panda
{
public static function whoAmI()
{
return static::getType();
}
public static function getType()
{
return 'I am a Giant panda!';
}
}
class RedPanda extends Panda
{
public static function getType()
{
return 'I am a Red panda!';
}
}
You'll notice that all we've done is replaced self
with static
. Now let's try executing the code once more.
I am a Giant panda!
I am a Red panda!
There we go! PHP has now respected the inheritance, and the overriding of the getType()
method. The world is once again... dandy!
Understanding the concept of statics can be a tricky business. It was not until very late into my career as a PHP developer that I started to use them effectively. If you find this chapter a little confusing, I'd suggest moving ahead using class instances for now, and coming back to this chapter with a little more experience.
For now at least, you know how to identify static properties and methods by their keyword.
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!