0

我已经创建了我遇到的问题的简短演示。这并不完全是我实现它的方式,但似乎会导致相同的结果。

<?php

class mainclass {

    var $vardata = array();

    function &__get ($var) {
        if ($this->vardata[$var]) return $this->vardata[$var];
        if ($var == 'foo') return $this->_loadFoo();
        return NULL;
    }

    function __set ($var, $val) {
        $this->vardata[$var] = $val;
    }

    function __unset($var) {
        unset($this->vardata[$var]);
    }

}

class extender extends mainclass {

    function __construct() {

        var_dump($this->foo);
        $this->_loadFoo();
        echo '<br>';
        var_dump($this->foo);

    }

    function _loadFoo () {

        unset($this->foo);
        $this->foo = array();

        $this->foo[] = 'apples';
        $this->foo[] = 'oranges';
        $this->foo[] = 'pears';

        return $this->foo;

    }

}


$test = new extender;

?>

上述代码的输出是:

array(3) { [0]=>  string(6) "apples" [1]=>  string(7) "oranges" [2]=>  string(5) "pears" }
array(5) { [0]=> string(6) "apples" [1]=> string(7) "oranges" [2]=> string(5) "pears" [3]=> string(7) "oranges" [4]=> string(5) "pears" } 

正如我所期待的那样:

array(3) { [0]=>  string(6) "apples" [1]=>  string(7) "oranges" [2]=>  string(5) "pears" }
array(3) { [0]=>  string(6) "apples" [1]=>  string(7) "oranges" [2]=>  string(5) "pears" }

__get、__set 和 __unset 函数都在正确的位置被调用,所以我希望函数的第二个直接调用简单地取消设置 $this->foo 并用相同的数据再次填充它。这意味着 var_dumping 它会给出相同的输出。相反,它最终完成了上述操作……用直接设置的三个字符串中的两个填充它,并保留最初设置的前三个字符串。

也许只是一个愚蠢的错误或对重载函数的误解 - 无论哪种方式,我已经被困在这里太久了,所以非常感谢任何帮助!

4

1 回答 1

0

您的代码有很多问题:

  • if ($this->vardata[$var])不是检查变量是否存在的方法;isset或(如果允许 null,则array_key_exists)是。
  • mainclass调用它没有的函数。你应该声明它是抽象的(否则它仍然可以工作,但如果你实例化了主类,你就会暴露在错误中)。
  • 如果您想_loadFoo设置缺少的数组元素(使用附带效果)或返回foo属性的默认值,您并没有考虑。由于您通过引用返回 in __get,我想您想要一个实际变量而不仅仅是一个返回值,所以我选择了第一条路线。你已经_loadFoo做了两件事——设置缺失的数组索引并返回值;为了使您没有直接设置数组索引的事情复杂化,您依赖于重载。

修正版:

<?php

abstract class mainclass {

    var $vardata = array();

    function &__get ($var) {
        if (isset($this->vardata[$var])) return $this->vardata[$var];
        if ($var == 'foo') {
            $this->_loadFoo(); /* called for collaterals */
            return $this->foo;
        }
        return NULL;
    }

    abstract function _loadFoo();

    function __set ($var, $val) {
        $this->vardata[$var] = $val;
    }

    function __unset($var) {
        unset($this->vardata[$var]);
    }

}

class extender extends mainclass {

    function __construct() {

        var_dump($this->foo);
        $this->_loadFoo();
        echo '<br>';
        var_dump($this->foo);

    }

    function _loadFoo () {

        unset($this->foo);
        $this->foo = array();

        $this->foo[] = 'apples';
        $this->foo[] = 'oranges';
        $this->foo[] = 'pears';

    }

}

$test = new extender;
于 2010-06-23T15:30:54.723 回答