2011-11-20 40 views
1

例PHP代碼:offsetSet沒有被調用在ArrayObject的

class TestArrayObject extends ArrayObject { 
    function offsetSet($index,$val){ 
     echo $index.':'.$val.PHP_EOL; 
    } 
} 

$s = new TestArrayObject(); 

//test 1 
$s['a'] = 'value';//calls offsetSet 
//test 2 
$s['b']['c'] = 'value';//does not call offsetSet, why? 

var_dump($s); 

爲什麼不測試2呼叫的offsetSet方法?

回答

1

ArrayObject是一大塊魔法,因此我不會推薦使用它,或者 - 更糟 - 擴展它。

但您的實際問題與ArrayObject本身沒有關係。你遇到的是$s['b']['c'] = ...;是所謂的間接修改'b'抵消。在PHP執行它的代碼看起來大致是這樣的:

$offset =& $s['b']; 
$offset['c'] = ...; 

正如你可以看到'b'從不直接寫入偏移。取而代之的是參考獲取,並且參考被修改。這就是爲什麼offsetGet將被稱爲,而不是offsetSet

+0

感謝,這說明它。 –

0

對於多維數組,請參閱用戶貢獻筆記here

+0

這不會修復間接調用。 – Tivie

0

這是怎樣的「疑難雜症」,因爲我認爲,預期的行爲是在規定的OP是問題。

此外,在將ArrayObject作爲對象或數組訪問時,行爲並不一致。

例子:

$foo['b']['c'] = 'value'; // no warning 
var_dump($foo); 

$bar->b->c = 'value'; // triggers warning 
var_dump($bar); 

我是有我自己的類同樣的煩惱,擴展ArrayObject的。我無法解決問題,但通過實施一種新的方法來設法解決問題,我使用這種方法來鏈式屬性創建。

class Arraylist extends ArrayObject 
{ 
    public function set($key, $value = null) 
    { 
     if (!is_null($value)) { 
      $val = new ArrayList((array) $value); 
     } else { 
      $val = new ArrayList(); 
     }  
     $this->offsetSet($key, $val); 
     return $this->offsetGet($key); 
    } 

    public function offsetSet($index,$val){ 
     echo $index.':'.$val.PHP_EOL; 
     parent::offsetSet($index, $val); 
    } 
} 

使用有機磷農藥例如:

代碼:

$s = new ArrayList(); 
$s->set('a', 'value'); 
$s->set('b')->set('c', 'another value'); 
var_dump($s); 

輸出:

0:value 
a:ArrayList 
0:value 
b:ArrayList 
0:another value 
c:ArrayList 
0:another value 

class ArrayList#5 (2) { 
    public $a => 
    class ArrayList#7 (1) { 
     string(5) "value" 
    } 
    public $b => 
    class ArrayList#8 (1) { 
    public $c => 
    class ArrayList#9 (1) { 
      string(13) "another value" 
    } 
    } 
} 
+0

感謝您分享您的經驗! –

+0

沒有問題,希望它有幫助 – Tivie

相關問題