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は同じ出力を提供します。代わりに、まあ、それは上記を行うことになります...直接設定された3つの文字列のうちの2つで埋め、最初の3つの最初に設定された文字列を保持します。

おそらく、単なるばかげた間違いか、オーバーロード関数の誤解です。いずれにせよ、私はここで長い間立ち往生しているので、助けていただければ幸いです。

4

1 に答える 1

0

コードには多くの問題がありました。

  • if ($this->vardata[$var])変数が存在するかどうかを確認する方法ではありません。issetまたは(nullが許可されている場合、array_key_exists)はです。
  • それmainclassが持っていない呼び出された関数。抽象的であると宣言する必要があります(それ以外の場合でも機能しますが、メインクラスをインスタンス化するとバグにさらされることになります)。
  • 欠落している配列要素を設定したり(付随的な効果を処理したり)、プロパティ_loadFooのデフォルト値を返したい場合は、気にしませんでした。fooで参照して戻って__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 に答える