Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't late static binding work with variables in PHP 5.3?

Let's start off with some code:

class Super {

    protected static $color;

    public static function setColor($color){
        self::$color = $color;
    }

    public static function getColor() {
        return self::$color;
    }

}

class ChildA extends Super { }

class ChildB extends Super { }

ChildA::setColor('red');
ChildB::setColor('green');

echo ChildA::getColor();
echo ChildB::getColor();

Now, late static binding in PHP 5.3 using the static keyword works great with static methods, so I assumed it would do the same magic on static variables. Well, seems it doesn't. The example above does not print out "red" and then "green" as I first expected, but "green" and "green". Why doesn't this work on variables when it works on methods? Is there any other way to achieve the effect I expected?

like image 487
Johan Fredrik Varen Avatar asked May 14 '11 07:05

Johan Fredrik Varen


1 Answers

Late static binding will only work for new definitions of variables / methods. Thus, in your example, the $color property of Super will always be modified instead of ChildA or ChildB. To make use of late static binding, you need to use the static keyword instead of self. Furthermore, you need to redefine the $color property of your ChildA and ChildB classes:

class Super {

    protected static $color;

    public static function setColor($color){
        // static instead of self
        static::$color = $color;
    }

    public static function getColor() {
        // static instead of self
        return static::$color;
    }

}

class ChildA extends Super {
    protected static $color;
}
class ChildB extends Super {
    protected static $color;
}

ChildA::setColor('red');
ChildB::setColor('green');

echo Super::getColor(); // prints nothing (NULL = ''), expected
echo ChildA::getColor();// prints red
echo ChildB::getColor();// prints green
like image 139
Lekensteyn Avatar answered Oct 11 '22 03:10

Lekensteyn