tags:

views:

744

answers:

8

I'm attempting to access member variables in a child class via the parent class without instantiation.

This is one of my attempts but B::getStatic() fails with Access to undeclared static property.

Is there another solution to this, possibly without static?

class A {

    static public function getStatic() {

        return self::$myStatic;

    }

}

class B extends A {

    public static $myStatic = 5;

}

class C extends A {

    public static $myStatic = 6;

}

var_dump(B::$myStatic);
var_dump(B::getStatic());

var_dump(C::$myStatic);
var_dump(C::getStatic());
A: 

$myStatic must be declared static in class A: See here.

mdm
A: 

You have a mismatch between the declaration of the function and variable.

Either you need to move the declaration of the function to B

or

move the declaration of the variable to A.

cbrulak
I need to keep the variable in B and the function in A. Is there another way around it, maybe without statics?
Gerald Kaszuba
Not that I know of, that's the basics of OOP.
cbrulak
A: 

Class B inherits the properties from class A instead of the reverse.

Why don’t you use B::$myStatic like in your example?

Gumbo
Because I am accessing the variable from A.
Gerald Kaszuba
It doesn’t matter from where you access it as long as the class is available.
Gumbo
class A { function get() { B::$myStatic; }} } wont work because I won't know what "B" is when I call get()
Gerald Kaszuba
A parent class doesn’t know if and what other classes inherited from it. You have to tell it that.
Gumbo
A: 
class A {
    public static $myStatic = 5;
}    
class B extends A {
    public static $myStatic = 3;
}
class C extends A {
    public static $myStatic = 1;
}

Then just use B::$myStatic ...

Luca Matteis
A: 

You have to move myStatic into A. Your method getStatic in A can't access a variable that does not exist in A.

psycho
A: 

From the PHP manual:

Static references to the current class like self:: or __CLASS__ are resolved using the class in which the function belongs, as in where it was defined:

So because the method is defined in A, when you call getStatic() on B or C it is trying to return a::$myStatic, which doesn't exist. Even if it did exist you would only ever get that value back, not any overridden value in a subclass.

A solution is Late Static Bindings, but this is only available in PHP 5.3 which is not yet released.

Tom Haigh
+1  A: 

The others are right, the way your code is it can't be done since the variable doesn't exist at compile time.

The way to do something like this is usually with an abstract class (available in PHP5 and up, it looks like).

Class A would be the abstract class, and would have a getStatic() function. Classes B and C would extend A and have definitions for the getStatic() function. This way, when you call getStatic() you will get the value the subclass defines since there is no definition in A.

The caveat to this approach is that you can't instantiate A since it's abstract. You would ALWAYS have to make a B or a C (or a subclass there-of).

You could also make a setter in A and have the subclasses use it to set the value (instead of an '='s). That would let you instantiate A and it could set the value if it ever needs to. You might be able to make the setter private so it can't be called directly, I don't know if subclasses can use private functions in PHP.

MBCook
+2  A: 

The concept you're running into is called "Late Static Binding." Until PHP 5.3.0, there was no support for this.

If you're running 5.3.0 or higher, update the getStatic() method:

static public function getStatic() {

return static::$myStatic;

}

Encoderer