2010-06-23 56 views
0

我已經創建了我遇到的問題的簡短演示。這不完全是我如何實現它,但似乎導致相同的結果。使用__get,__set和__unset的類中的意外數組內容

<?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它會給出相同的輸出。相反,它最終會完成上述操作......用三個字符串中的兩個直接設置並保留前三個原始字符串。

也許只是一個愚蠢的錯誤或對重載函數的誤解 - 無論哪種方式,我一直在這裏卡住了太久,所以任何幫助都非常感謝!

回答

0

有很多東西你的代碼錯誤:

  • if ($this->vardata[$var])是不檢查的方式是一個變量存在; isset或(如果允許爲null,array_key_exists)是。
  • mainclass調用它沒有的函數。你應該聲明它是抽象的(否則它仍然可以工作,但是如果你實例化了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; 
+0

感謝。添加isset將它排序在我的實現中,在那裏進行一些監督。指出的其他問題是關於我發佈的示例代碼的相關觀點 - 感謝您花時間瀏覽它。 – JoeR 2010-06-23 15:41:21