Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
928 views
in Technique[技术] by (71.8m points)

php - Inherit static properties in subclass without redeclaration?

I'm having the same problem as this guy with the application I'm writing right now. The problem is that static properties are not being inherited in subclasses, and so if I use the static:: keyword in my main class, it sets the variable in my main class as well.

It works if I redeclare the static variables in my subclass, but I expect to have a large number of static properties and subclasses and wish to avoid code duplication. The top-rated response on the page I linked has a link to a few "workarounds", but it seems to have 404'd. Can anyone lend me some help or perhaps point me in the direction of said workarounds?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I'm not sure what specific workaround it was talking about, I can think of quite a few that can work. I personally wouldn't use these in any code. I'd recommend you take a look Is it possible to overuse late static binding in PHP? and rethink if there's a better way to do whatever you hope accomplish.

Also keep in mind my code is completely untested as I wrote it just here.

Method 1: Always use an array to figure

All the other methods are based on this one. Whereever you use the static property, you insert the code to detect the class and get it. I would only consider this if you never plan on using the property anywhere else.

$class = get_called_class();
if(isset(self::$_names[$class])) {
    return self::$_names[$class];
}
else {
    return static::NAME_DEFAULT;
}

Method 2: Use a getter/setting methods

If you plan on having it used in more than one spot, this method would be better. Some singleton patterns use a similar method.

<?php
class SomeParent {
    const NAME_DEFAULT = 'Whatever defaults here';

    private static $_names = array();

    static function getName($property) {
        $class = get_called_class();
        if(isset(self::$_names[$class])) {
            $name self::$_names[$class];
        }
        else {
            $name = "Kandy"; // use some sort of default value
        }
    }

    static function setName($value) {
        $class = get_called_class();
        self::$_names[$class] = $value;
    }
}

Method 3: __callStatic

This is by far the most convenient method. However you need to have an object instance to use it (__get and __set can't be used statically). It is also slowest the method (much slower than the other two). I'm guessing that since you're already using static properties this is already a non-option. (If this method works for you, it'd be probably be better if you didn't use static properties)

<?php
class SomeParent {

    const NAME_DEFAULT = 'Whatever defaults here';

    private static $_names = array();

    function __get($property) {
        if($property == 'name') {
            $class = get_called_class();
            if(isset(self::$_names[$class])) {
                return self::$_names[$class];
            }
            else {
                return static::NAME_DEFAULT;
            }
        }
        // should probably trigger some sort of error here
    }

    function __set($property, $value) {
        if($property == 'name') {
            $class = get_called_class();
            self::$_names[$class] = $value;
        }
        else {
            static::$property = $value;
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...