以下是数据迭代器实现
//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
请注意,输出中不包含我的私有和受保护属性(年龄、地址)输出。
如何告诉Iterator也输出这些?
您不能告诉迭代器输出这些属性,因为它们根本无法从外部访问(即迭代器执行get_object_vars($this->data)
.的点
有两种方法可以做到这一点:
- 通过让数据对象将值传递给迭代器
- 使用反射API强制将它们拉出(冗长,缓慢!)
但是,在将#1作为首选选项之前,先停下来问问自己:为什么迭代器公开数据对象的非公共成员
制作private
意味着"你们真的不需要知道这件事;它可能在未来消失,也可能会变得面目全非"。如果它是外界关心的东西,那么为什么它不是public
(直接或通过公共getter公开)?重新思考这个迭代器的目的可能是什么。
也就是说,以下是你将如何做#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));
}
}
Public、private和protected是访问修饰符。它们旨在限制类属性的可访问性。
- Public意味着任何人都可以访问该属性,因此如果有人想要,他们可以更改值,而无需您知道
- Private表示属性只能在类内部访问,所以没有人可以从类外"搅乱"这些属性
- Protected类似于Private,但子类(从那个类继承)有权访问它
您将age
和address
设为私有,所以您基本上是在说,不允许任何人访问这些属性。如果你想访问私有/受保护的属性,你必须制作getter和setter并调用这些函数,或者将这些属性公开。
尝试get_class_vars
$this->properties = get_class_vars(get_class($this->data));
而不是$this->properties=get_object_vars($this->数据);