Static properties and methods - how do they work?

I do not fully understand how static properties and methods work (http://www.php.net/manual/en/language.oop5.static.php) I have read that “a static property is available to all instances of a class, so you can set values that you want to be avialable to all members of a type.” Is this just wrong? I think of objects more or less as self-contained containers of structured data, which each one being independent of others. This quote appears to say that if I alter a static property, other objects (extant or yet to be made) will be changed as well.

Example:

class Test
{
	public $example;
	static $static_example;


	public function setExample($example)
	{
		$this->example = $example;
	}

	public function setStaticExample($static_example)
	{
		$this->static_example = $static_example;
	}

}


$test1 = new Test();
$test2 = new Test();

$test1->setExample('a normal non-static property');
$test1->setStaticExample('a static example set in test1');

echo "$test1->example";
echo "$test1->static_example";

echo "$test2->static_example";

But this gives an error: “Notice: Undefined property: Test::$static_example”

Which appears to me to say I am either misinterpreting static properties or my code is wrong.

A related question:

Why does putting

	public function getStaticExample()
	{
		return $static_example;
	}

into the Test class and then using

echo "$test->getStaticExample()";

above return an error?

“Notice: Undefined variable: static_example”
“Notice: Undefined property: Test::$static_example”

Doing the same with

	public function getExample();
	{
		return $example;
	}

does not return an error.

Do getters or setters not work with static properties?

Static properties are essentially global variables, and so using them has all the same downsides… they make your code tightly coupled, hard to test, and open the way for hard-to-debug problems.

Where you’re going wrong in your example code is that you’re trying to access the static property using $this. The $this variable represents the current instance of a class, but static properties exist on the class itself, not the instances, which is why you can’t call $this->static_example. From within an instance, you can access the class using the self keyword:


class Test
{
	static $static_example;

	public function setStaticExample($static_example)
	{
		self::$static_example = $static_example;
	}

}

$test1 = new Test();
$test1->setStaticExample('a static example set in test1');


although there’s not much point in having getter/setter methods, as you can access static properties more directly:


Test::$static_example = 'Hello, world!';
echo Test::$static_example;

Static methods work much the same, and some frameworks/libraries use them to provide easy access to utility functions and the like, but it’s generally considered bad practice for the reasons I mentioned above.


// Set a session variable with a static helper method
Session::set('username', $username);

You use them similarly as instance properties/methods, the only difference is that they are applied on class and therefore exist independent on object instantiation. Just as Fretburner said, static properties/methods are considered Poor OOP Practices, you want to avoid them unless there is a good reason not to. To some extent its not bad thing if you dont know what statics are, since it prevents you from using them if you dont even know how to use them.

Okay, I now see about the self:: issue and why setters and getters are not good for static. Can you confirm though if I set a static property through using the self:: scope resolution operator whether all NEW or EXISTING objects will also be changed? That seemed unintuitive to me in that quote so, so I want to be sure of what’s the case. Or if a static method or property is just basically a normal variable/function that can be called, except I have to do it through the class itself and it has no special object-influencing results besides that.

Thank you.

Yes, that’s right. Any object of that class, new or existing, will be accessing the same static variable.

Thanks. I’m glad I was able to confirm that. I know it would have got me sooner or later otherwise!