2012-03-11 89 views
1

如果我使用magic __set將值設置爲private var我怎樣才能將var設置爲數組?帶有數組的PHP getters和setters

的是這樣的即時通訊思想,假裝我有一類__get __set

$myclass->names = 'Name'; // Works 
$myclass->names = array('n1'=>'Name1', 'n2' => 'Name2'); // works as well 

//this does not work 
$myclass->names['n1'] = 'Name1'; 
$myclass->names['n2'] = 'Name2'; 

它,我想獲得工作的最後2個例子。已經測試過各種方法,但無法弄清楚。

+0

你得到一個錯誤或警告? – 2012-03-11 10:41:30

回答

2

它不起作用。 $class->arr['key']將執行吸氣劑。所以基本上,你的代碼看起來是這樣的:

array('key' => 'value')['key'] = 'new value'; 

哪一個顯然什麼都不做。如果你想要這樣做,你將不得不聲明names作爲公共財產。

+2

雖然你說得對「它不起作用」,你解釋爲什麼是明顯錯誤的。 – rodneyrehm 2012-03-11 10:57:55

1

這個表達式將調用獲取方法:

$myclass->names['n1'] = 'Name1'; 
^^^^^^^^^^^^^^^ 
needs to be get 
       ^^^^^^^^^^^^^^^^ 
       assignment later 

只有這樣,才能使這項工作是一個解決辦法是fugly。通過讓獲取者返回一個參考到知道數組,下面的分配可以工作。

function & __get($name) { 

    if (is_array($this->$name)) { 
      return & $this->$name; 
    } 
    else ... 
} 

所以它真的只是建議如果顯著簡化你的API。

1

你顯然不輸出通知,否則你已經得到了錯誤

注意:過載性能美孚:: $酒吧的間接修改沒有 效果

你什麼'試圖做的事根本不可能。只有一種方法可以通過__get寫入陣列,但這很可能不是您想要的。

<?php 

class Foo { 
    protected $bar = array(); 

    public function &__get($name) { 
     return $this->$name; 
    } 

    public function __set($name, $value) { 
     return $this->$name = $value; 
    } 
} 

$foo = new Foo(); 
$foo->bar = array('a', 'b', 'c'); 
echo $foo->bar[0]; // output "a" 
$foo->bar[0] = 'z'; // fires warning 
echo $foo->bar[0]; // output "z" 

// all fine, but here's the catch: 
$t =& $foo->bar; 
$t = array('y'); 
echo $foo->bar[0]; // output "y" 

現在,您已經看到了如何通過引用返回值可以是一個問題,你可能有興趣在ArrayObject。像

<?php 

class Foo { 
    protected $bar = array(); 

    public function __get($name) { 
     return new ArrayObject(&$this->$name); 
    } 

    public function __set($name, $value) { 
     return $this->$name = $value; 
    } 
} 

$foo = new Foo(); 
$foo->bar = array('a', 'b', 'c'); 
echo $foo->bar[0]; // output "a" 
$foo->bar[0] = 'z'; // fires warning 
echo $foo->bar[0]; // output "z" 

// all fine, and no catch 
$t =& $foo->bar; 
$t = array('y'); 
echo $foo->bar[0]; // still outputs "z" 
+0

是的,我在輸出中遇到了一些錯誤,但是自從我在最後一次在這個星期五一起工作時,我已經忘記了它。我改爲使用現在的公共var,它的工作原理如下 – Deko 2012-03-11 11:17:26

0

東西試試這個代碼:

class Foo 
 
{ 
 
    private $bar; 
 

 
    public function __construct() 
 
    { 
 
     $this->bar = new ArrayObject(array()); 
 
    } 
 

 
    public function __get($item) 
 
    { 
 
     if(property_exists($this, $item)) { 
 
      return $this->$item; 
 
     } 
 
    } 
 

 
    public function __set($item, $value) 
 
    { 
 
     if(property_exists($this, $item)) { 
 
      $this->{$item} = $value; 
 
     } 
 
    } 
 
} 
 

 
$obj = new Foo(); 
 
$obj->bar['color'] = 'green'; 
 
foreach($obj->bar as $attribute => $value) { 
 
    echo '<p>' . $attribute . ' : ' . $value . '</p>' . PHP_EOL; 
 
} 
 
// output => color : green

+0

這個類私有地聲明'bar',但是調用代碼訪問它就好像它是公共的。這不起作用。 – 2015-04-11 12:52:48

+0

當然這會因公共魔術吸氣/吸氣方法而起作用。實際上,當你說'echo $ obj-> bar'時,'__get方法被調用'bar'參數發送給它,當你說'$ obj-> bar = 5;'setter被調用''bar''和'5'參數。閱讀更多關於魔法的方法。 – MLF 2015-05-13 16:23:07

+0

我不記得寫評論......但我清楚地沒有正確地閱讀你的代碼。你當然是對的。 – 2015-05-13 16:26:00

相關問題