Static versus non-static methods and properties
In your work with classes, one of the most important things to understand is the difference between static and non-static methods and properties. The key distinction is that static properties exist in the context of the class, and non-static properties exist only in the context of an object.
Accessing static methods and properties from your scripts is easy. If they’re public, just use the name of the class, followed by a double colon, followed by the static property or method you’re accessing. For properties, you need to include the dollar-sign. Without the dollar-sign, PHP looks for a class constant with that name. Here’s a class called StaticExamples:
{show example}
It defines a static property called ‘$helloWorld’. Over here in my test script:
{show test script}
, you can see I just write StaticExamples::$helloWorld to access it. Here’s the output:
{show output}
Static methods cannot access non-static properties and methods, because no object context exists for them. For a static method, the variable $this has no meaning, and because it has no meaning, there is no point of reference by which a non-static method or property can be called. At least, not directly. I’ll explain this more at the end.
On the other hand, non-static methods have no problem accessing static properties and methods. With static properties, if it gets changed at one part of the script, that change is reflected anywhere else that property is checked. I realize with a name like static, you’d think it couldn’t change at all, but static properties act just like regular variables. And actually, they’re often a good replacement for global variables.
So, consider this class:
{show example}
It defines a static property called $_changeme, a non-static property called _changeMeNS (the NS stands for non-static), and two non-static methods called setProps and getProps.
Those two non-static methods have to be invoked on instances of the StaticExamples class. Notice that once you call setProps with 2 arguments, it sets the static property $_changeMe to the first argument, and the non-static property _changeMeNS to the second argument.
Here’s a test script I wrote to go along with this lesson.
{show example}
The first thing it does is create three objects of the StaticExamples class. Then it calls the setProps method on each. Once it’s done that it calls the getProps method on each and displays their outputs. Let’s look at that now.
{switch to output}
Notice that the property labelled ‘static’ is a 3 on all of them, but they each have a different ‘non-static’ property. The reason for this is that only one StaticExamples::$_changeMe exists. And every call to setProps was also setting the $_changeMe variable. And now that I’m checking that variable, only the last value of $_changeMe exists.
As for the ‘non-static’ properties, they persist with the objects where they were set. So $SE1’s non-static property is still a 1, and $SE2’s non-static property is still a 2. Each object contains its own copies of its non-static properties, but they all accessed the exact same static property.
Now, looking back at the code, I want to point out the keyword ‘self’. It’s sort of like a static equivalent to ‘$this’. Each time I used ‘self’ I could have used the full class name ‘StaticExamples’ instead. I used ‘self’ because it’s a convenient shorthand for accessing static methods and properties from within the context of the class.
Now, a static method cannot access a non-static method or property directly, as I explained before. See my static method ‘doSomething’?
{show example}
It’s going to trigger a fatal error as soon as I try to use it. Watch:
{type StaticMethods::doSomething(); into test script}
{show output containing fatal error}
However, if you really wanted to, you could create a static property which is itself an object of your class, and then you could use that static property, within your static methods, to run non-static methods and access non-static properties.
Notice I’ve written 2 more methods in my StaticExamples class, called setPropsStatic, and getPropsStatic. They’re similar to setProps and getProps, but can be called from a static context.
{show example code}
The way they work, is they first check whether the variable $_instance, a private, static property, is null or not. If it is, they set it to a new object of StaticExamples. And that property will still be set the next time one of these methods looks for it. Next they run whatever code they need to. Notice in ‘setPropsStatic’ it’s using self::$_instance to access a private, non-static property. When a static method creates an instance of its own class, it can use that instance object as a handle for accessing private and protected methods or properties on it. We’re going to use that fact later when I show you how the Singleton pattern works.
Now, going back to my test script, I’ll put StaticExamples::setPropsStatic(0,0); in front of my call to $SE1->setProps, and I’ll stick StaticExamples::getPropsStatic(); right before $SE1->getProps. Now let’s look at how the output has changed.
{show output}
Notice, the static property on getPropsStatic is a 3, same as all the others. But it’s non-static property is a 0, just like when it was set. That’s because in the context of StaticExamples::$_instance, the property _changeMeNS has only been set one time.
January 23 2010 02:56 pm | Schmategories
One Response to “Static versus non-static methods and properties”
intel352 on 22 Feb 2010 at 3:06 pm #
You forgot to replace your {show example…} and {show output} bits in your post…