使用实现 ArrayAccess 和 Iterator 的对象作为可变参数
Using object implementing ArrayAccess and Iterator as variadic parameter
我有一个 class 实现了 ArrayAccess and Iterator。
我正在尝试弄清楚如何将此对象可变参数传递给本机函数,例如 array_merge
:
array_merge(...$object);
令我失望的是,我收到一条错误消息,指出 $object
不是数组。
array_merge(): Argument #1 is not an array
我查看了这些其他接口,但没有一个看起来很明显:IteratorAggregate, Serializable, Countable. Also ArrayObject 结果是死胡同。
我确实有一个 getter 用于转换为数组。但我有点想通过实现 ArrayAccess 或 Iterator 来发现我的 $object 转换为数组,因为它是关于展开数组的。
我可以实现另一个接口来使我的 class 更像数组吗?
这是 the migration guide from 5.5.x to 5.6.x in the manual 中记录的新语言功能(第 通过 ...
解包的参数),您必须使用 5.6.x
运行时。
如果无法升级运行时,则必须使用 getter 将其转换为数组(类似于 ArrayObject
's getArrayCopy
):
call_user_func_array('array_merge', $arr->getArrayCopy());
测试
下面的代码(基于 PHP 的 ArrayAccess
and Iterator
文档示例)在 PHP 5.6.2
、5.6.17
和 [=21] 上成功执行=].它在旧版本(5.5.31
及更旧版本)上确实失败了。
$arr = new MyArray();
$arr[0] = array(1, 2);
$arr[1] = array(3, 4);
// MyArray
print(get_class($arr));
// Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 )
print_r(array_merge(...$arr));
实施MyArray
:
class MyArray implements ArrayAccess, Iterator
{
private $container = array();
private $position = 0;
public function getArrayCopy() {
return $this->container;
}
public function offsetSet($offset, $value) {
if (is_null($offset)) {
$this->container[] = $value;
} else {
$this->container[$offset] = $value;
}
}
public function offsetExists($offset) {
return isset($this->container[$offset]);
}
public function offsetUnset($offset) {
unset($this->container[$offset]);
}
public function offsetGet($offset) {
return isset($this->container[$offset]) ? $this->container[$offset] : null;
}
function rewind() {
$this->position = 0;
}
function current() {
return $this->container[$this->position];
}
function key() {
return $this->position;
}
function next() {
++$this->position;
}
function valid() {
return isset($this->container[$this->position]);
}
}
我有一个 class 实现了 ArrayAccess and Iterator。
我正在尝试弄清楚如何将此对象可变参数传递给本机函数,例如 array_merge
:
array_merge(...$object);
令我失望的是,我收到一条错误消息,指出 $object
不是数组。
array_merge(): Argument #1 is not an array
我查看了这些其他接口,但没有一个看起来很明显:IteratorAggregate, Serializable, Countable. Also ArrayObject 结果是死胡同。
我确实有一个 getter 用于转换为数组。但我有点想通过实现 ArrayAccess 或 Iterator 来发现我的 $object 转换为数组,因为它是关于展开数组的。
我可以实现另一个接口来使我的 class 更像数组吗?
这是 the migration guide from 5.5.x to 5.6.x in the manual 中记录的新语言功能(第 通过 ...
解包的参数),您必须使用 5.6.x
运行时。
如果无法升级运行时,则必须使用 getter 将其转换为数组(类似于 ArrayObject
's getArrayCopy
):
call_user_func_array('array_merge', $arr->getArrayCopy());
测试
下面的代码(基于 PHP 的 ArrayAccess
and Iterator
文档示例)在 PHP 5.6.2
、5.6.17
和 [=21] 上成功执行=].它在旧版本(5.5.31
及更旧版本)上确实失败了。
$arr = new MyArray();
$arr[0] = array(1, 2);
$arr[1] = array(3, 4);
// MyArray
print(get_class($arr));
// Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 )
print_r(array_merge(...$arr));
实施MyArray
:
class MyArray implements ArrayAccess, Iterator
{
private $container = array();
private $position = 0;
public function getArrayCopy() {
return $this->container;
}
public function offsetSet($offset, $value) {
if (is_null($offset)) {
$this->container[] = $value;
} else {
$this->container[$offset] = $value;
}
}
public function offsetExists($offset) {
return isset($this->container[$offset]);
}
public function offsetUnset($offset) {
unset($this->container[$offset]);
}
public function offsetGet($offset) {
return isset($this->container[$offset]) ? $this->container[$offset] : null;
}
function rewind() {
$this->position = 0;
}
function current() {
return $this->container[$this->position];
}
function key() {
return $this->position;
}
function next() {
++$this->position;
}
function valid() {
return isset($this->container[$this->position]);
}
}