2013-02-14 72 views
1

下面是數據迭代器實現不能訪問私有保護成員的迭代器PHP

//Data Iterator 
    class DataIterator implements Iterator 
    { 
     public $data ; 
     public function __construct(Data $obj) 
     { 
      $this->data = $obj; 
     } 
     public function rewind() 
     { 
      $this->properties = get_object_vars($this->data);      
     } 
     public function valid() 
     { 
      if (key($this->properties) === null) 
      { 
       return false; 
      } 
      return true; 
     } 
     public function key() 
     { 
      return key($this->properties); 
     } 
     public function current() 
     { 
      return current($this->properties); 
     } 
     public function next() 
     { 
      next($this->properties); 
     } 

    } 

,這裏是數據類

/*Data Class*/ 
    class Data implements IteratorAggregate 
    { 
     public $name; 
     private $age; 
     protected $address; 
     public $country; 
     public $state; 

     public function __construct($name, $age, $address, $country = 'USA', $state = 'NH') 
     { 
      $this->name = $name; 
      $this->age = $age; 
      $this->address = $address; 
      $this->country = $country; 
      $this->state = $state; 
     } 
     function getIterator() 
     {  
      return new DataIterator($this); 
     } 
    } 

這裏是主叫方

$data = new Data('Joker', '27', 'California'); 

    foreach($data->getIterator() as $key => $value) 
    { 
     echo $key , ' ', $value, '<br>'; 
    } 

輸出

name Joker 
country USA 
state NH 

請注意,輸出不包含我的私有和受保護屬性(年齡,地址)輸出。

我該如何告訴迭代器輸出這些呢?

回答

1

您可以迭代說不出來輸出那些屬性,因爲他們根本無法從外部訪問(即在迭代器get_object_vars($this->data)

有兩種方法,你可以去這樣做。

  1. 通過具有數據對象值傳遞給迭代器。
  2. 使用反射API來拉他們一把由力(冗長,緩慢的!)。

但是在繼續使用#1作爲首選選項之前,先停下來問問自己:爲什麼迭代器會公開數據對象的非公共成員?

製作東西private的意思是「你們不需要知道這件事,它可能會在未來消失,或者它可能會變得無法識別」。如果這是外界關心的事情,那麼爲什麼它不是public(直接或通過公共獲取者暴露)?重新思考這個迭代器的目的是什麼。

這就是說,這裏是你會怎麼做?#1:

class DataIterator implements Iterator 
{ 
    public $data; 
    private $properties; 
    public function __construct(Data $obj, array $propeties) 
    { 
     $this->data = $obj; 
     $this->properties = $properties; 
    } 

    public function rewind() 
    { 
     // Arguably horrible trick to refresh the property map without 
     // demanding that Data exposes a separate API just for this purpose 
     $newIterator = $this->data->getIterator(); 
     $this->properties = $newIterator->properties; 
    } 
} 

class Data implements IteratorAggregate 
{ 
    function getIterator() 
    {  
     return new DataIterator($this, get_object_vars($this)); 
    } 
} 
0

試get_class_vars

$this->properties = get_class_vars(get_class($this->data)); 

代替 $這 - >屬性= get_object_vars($這 - >數據);

1

公共,私人和受保護的是訪問修飾符。它們旨在限制類屬性的可訪問性。

  • 公共意味着任何人都無法訪問該屬性,因此,如果有人想要,他們可以改變的價值,不在於你知道它。
  • Private意味着該屬性只能在類INSERT中被訪問,因此沒有人可以與來自該類的外部屬性「混淆」。
  • 受保護與Private類似,但子類(類別 從該類繼承)可以訪問它。

您正在ageaddress私有的,所以你基本上是說,沒有人被允許訪問這些屬性。如果你想訪問私有/受保護的屬性,你必須讓getter和setter並調用這些函數,或者公開屬性。