gpt4 book ai didi

php - 为没有容器数组的 ArrayAccess 实现 Iterator 接口(interface)

转载 作者:行者123 更新时间:2023-12-01 13:10:03 27 4
gpt4 key购买 nike

这是我尝试实现 https://www.php.net/manual/en/class.iterator.php对于 ArrayAccess。许多示例使用容器数组作为私有(private)成员变量;但如果可能的话,我不想使用容器数组。我不想要容器数组的主要原因是因为我想像这样访问属性(数组键)$DomainData->domainId,同时具有智能感知等。

演示:https://ideone.com/KLPwwY

class DomainData implements ArrayAccess, Iterator
{
private $position = 0;
public $domainId;
public $color;

public function __construct($data = array())
{
$this->position = 0;
foreach ($data as $key => $value) {
$this[$key] = $value;
}
}

public function offsetExists($offset)
{
return isset($this->$offset);
}

public function offsetSet($offset, $value)
{
$this->$offset = $value;
}

public function offsetGet($offset)
{
return $this->$offset;
}

public function offsetUnset($offset)
{
$this->$offset = null;
}

/*****************************************************************/
/* Iterator Implementation */
/*****************************************************************/

public function rewind()
{
$this->position = 0;
}

public function current()
{
return $this[$this->position];
}

public function key()
{
return $this->position;
}

public function next()
{
++$this->position;
}

public function valid()
{
return isset($this[$this->position]);
}
}

调用它:

$domainData = new DomainData([
"domainId" => 1,
"color" => "red"
]);

var_dump($domainData);

foreach($domainData as $k => $v){
var_dump("domainData[$k] = $v");
}

实际:

object(DomainData)#1 (3) {
["position":"DomainData":private]=>
int(0)
["domainId"]=>
int(1)
["color"]=>
string(3) "red"
}

期望:

object(DomainData)#1 (3) {
["position":"DomainData":private]=>
int(0)
["domainId"]=>
int(1)
["color"]=>
string(3) "red"
}
string(24) "domainData[domainId] = 1"
string(23) "domainData[color] = red"

最佳答案

让我描述一下您可以如何做到这一点的几种方法。

带有自定义代码的 ArrayObject

ArrayObject实现您想要的所有接口(interface)。

class DomainData extends ArrayObject
{
public $domainId;
public $color;

public function __construct($data = array())
{
parent::__construct($data);
foreach ($data as $key => $value) {
$this->$key = $value;
}
}
}

不过,这不是很好;它复制键和值两次,更改属性不会更改底层数组。

在 get_object_vars() 上实现 IteratorAggregate

如果您不介意放弃ArrayAccess,您可以只实现一个aggregate iterator。 .

class DomainData implements IteratorAggregate
{
public $domainId;
public $color;

public function __construct($data = [])
{
foreach ($data as $key => $value) {
$this->$key = $value;
}
}

public function getIterator()
{
return new ArrayIterator(get_object_vars($this));
}
}

带有属性标志和文档 block 的 ArrayObject

更好的方法是使用文档 block 来描述您的属性(描述 here ),然后使用 ARRAY_AS_PROPS 标志将数组公开为属性。

/**
* Magic class
* @property int $domainId
* @property string $color
*/
class DomainData extends ArrayObject
{
function __construct($data = []) {
parent::__construct($data, parent::ARRAY_AS_PROPS);
}
}

当加载到 PhpStorm 中时,您会看到: phpstorm editor

关于php - 为没有容器数组的 ArrayAccess 实现 Iterator 接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60689674/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com