'PHP: Limiting static property scope to specific class
abstract class Mother {
protected static $foo = null;
protected static $bar = null;
public function getFoo() { return static::$foo; }
public function getBar() { return static::$bar; }
public function setFoo($foo) { static::$foo = $foo; }
public function setBar($bar) { static::$bar = $bar; }
}
class Brother extends Mother {
protected static $foo = 'BROTHERS';
}
class Sister extends Mother {
protected static $foo = 'SISTERS';
}
$brother1 = new Brother();
$brother2 = new Brother();
$sister1 = new Sister();
$sister2 = new Sister();
$sister1->setBar('ONLY SISTERS'); // We set $bar = 'ONLY SISTERS' at sister1.
// We want only Sister instances to get this value...
// however Brother instances also get this value!
echo '<p>Brother 1: Foo="'.$brother1->getFoo().'", Bar="'.$brother1->getBar().'"</p>';
// Foo="BROTHERS", Bar="ONLY SISTERS"
echo '<p>Brother 2: Foo="'.$brother2->getFoo().'", Bar="'.$brother2->getBar().'"</p>';
// Foo="BROTHERS", Bar="ONLY SISTERS"
echo '<p>Sister 1: Foo="'.$sister1->getFoo().'", Bar="'.$sister1->getBar().'"</p>';
// Foo="SISTERS", Bar="ONLY SISTERS"
echo '<p>Sister 2: Foo="'.$sister2->getFoo().'", Bar="'.$sister2->getBar().'"</p>';
// Foo="SISTERS", Bar="ONLY SISTERS"
So apparently if static::$bar is not explicitly redefined in every child (Brother, Sister) their parent (Mother) will set the value for them (or at least for those who did not redefine it).
The question: Is there any way to prevent children who did not redefine static::$bar from receiving the new value? In other words, how to make sure only the referred class gets a new value, EVEN if static::$bar is not explicitly redefined in every child?
Solution 1:[1]
No, not the way you're doing it. That's what private scope is for. Child classes inherit all public and protected static properties--which mean they all point to the same value whether they are a parent, child, or sibling.
This is correct and good OO.
You should define the variable it as private static in the parent class and then the child wouldn't be able to see it directly and could create their own private static variable with the same name if needed.
Provide static getters and setters in your class to access the private static property.
Brother::getFoo();
Sister::getFoo();
You can make the getFoo() in the parent class Mother abstract or not, if you need to access it directly make it non-abstract so you can do:
Mother::getFoo();
Solution 2:[2]
This is just madness.
You should understand that extend defines IS A relationship. For example : class Duck extends Bird{} this means that every instance of Duck is a Bird.
So in your example, every Brother is a Mother. I fail to see how this would make a sense.
And the other thing : why the hell are you abusing static variables? What you are doing there is not object oriented programming. You are just wrapping global scope variables and functions in a namespace ( which happens to look like class ).
Some additional links on the subject, you might find useful:
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Community |
