08.07.2007 / Object-oriented PHP :: A guide for fellow ISys junkies
Static keyword
As you learned in programming class, the static keyword allows you to access a class member without being in an object context. In other words, oftentimes you have a class that really only provides functionality; it’s not like a business object where you need to hold information temporarily, move the object around, pull the information back out, etc. A data access object comes to mind (DAO), but if you keep an eye out you’ll find that there are many times when you only need to use a class outside of an object context. The benefit of recognizing these cases is that you don’t have to instantiate the class every time you want to use it. So instead of calling bark() like this:
1 2 | $dog = new Dog(); $dog->bark(); |
You can just call it like this:
1 | Dog::bark(); |
Notice the double-colon. This is used instead of the arrow (->) when we’re not dealing with an instantiated object. So what do we need to make this possible? In PHP, very little. Take a look:
1 2 3 4 5 6 7 8 9 | class Dog { public function bark() { echo "Bark!"; } } Dog::bark(); |
It works. I never had to instantiate the class and the code in my Dog class really isn’t any different from just your ordinary class. Again, this is another example of just how relaxed PHP is. So why should we be cautious about being this relaxed? Let’s add one element:
1 2 3 4 5 6 7 8 9 10 11 | class Dog { private $mySound = "Bark!"; public function bark() { echo $this->mySound; } } Dog::bark(); |
This throws the following error:
[code]
Fatal error: Using $this when not in object context in /mnt/backside/vol/navyblue/spunky/aaronius/aaronhardy.com/php_sandbox/index.php on line 25
[/code]
Like the error says, we tried using $this-> outside of an object context (in other words, we’re not dealing with an instantiated object). So what if we change the $this-> to self::? To explain, self:: works just the same way as $this-> except it’s used outside of an object context and must be followed by a dollar sign when referring to a class variable. So, $this-> is used when we’re dealing with an instantiated object while self:: is used when we’re not dealing with an instantiated object. Here’s what I’m talking about:
1 2 3 4 5 6 7 8 9 10 11 | class Dog { private $mySound = "Bark!"; public function bark() { echo self::$mySound; } } Dog::bark(); |
While we’re getting closer, we now get this error:
[code]
Fatal error: Access to undeclared static property: Dog::$mySound in /mnt/backside/vol/navyblue/spunky/aaronius/aaronhardy.com/php_sandbox/index.php on line 25
[/code]
In other words, it’s saying that in order to access a class variable from a non-object context, we must declare that class variable as static. So let’s make one more modification to our code by declaring our class variable as static:
1 2 3 4 5 6 7 8 9 10 11 | class Dog { private static $mySound = "Bark!"; public function bark() { echo self::$mySound; } } Dog::bark(); |
Woot! No errors and we got the dog to bark. So, what do we learn from our tests? A class variable cannot be accessed in a non-object context without being declared static. On the other hand, a function can be accessed from a non-object context (i.e., no object instantiated) without being declared static! Ambiguous, yes. Even crazier, a function can be accessed from an object context (i.e., using an object) even if it is declared static. Although this is supposed to be a PHP “feature,” this is fairly disgruntling and I hope PHP 6 provides a more standard, clear-cut approach. So then, what good does the static keyword do in relation to class methods? From a functional standpoint, I can’t see that it does any good, but I still use it. Why? Because if I know at the time I code the method that it should only be called from a non-object context, I want to always remind myself of that whenever I look at the method while I’m coding.
Side Note
In PHP’s documentation on the static keyword, it states:
Calling non-static methods statically generates an E_STRICT level warning.
If this is true and my understanding is correct, then you should be able to crank up error reporting to report warnings and that should prevent you from calling a non-static method without an object. In my tests though, I received no errors. If anyone else has had different results, please join the intimate conversation.
So this would be my final code:
1 2 3 4 5 6 7 8 9 10 11 | class Dog { private static $mySound = "Bark!"; public static function bark() { echo self::$mySound; } } Dog::bark(); |
See the public static function part? The static there really isn’t doing anything for me except reminding me that I should only call the method from a non-object context.
Sorry to show what I consider some of the flaws of PHP, but I think it’s necessary if you actually want to know how to code it well and know why you’re coding it well.
One last note–if you ever see an error that says something about PAAMAYIM_NEKUDOTAYIM, it’s Hebrew and means “double colon.” It happens when you try using the double colon (::) within an object context, like so:
1 2 | $dog = new Dog(); $dog::mySound; |
Why did they make an error in Hebrew? I don’t know.

Nice site you have here Aaron! There’s just one small point that I think you might be interested in. You mentioned that PHP doesn’t support object overloading, but it actually does. Several special methods can be set up on objects, including __get, __set, and __call. This may not be the same implementation as is found in other languages, but it is overloading. Check it out.