2013-02-14 69 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并调用这些函数,或者公开属性。