Использование объекта, реализующего ArrayAccess и Iterator, как переменный параметр

У меня есть класс, который реализует оба ArrayAccess а также Итератор.

Я пытаюсь выяснить, как передать этот параметр объекта variadic в нативную функцию, как array_merge:

array_merge(...$object);

К моему разочарованию, я получаю сообщение о том, что $object это не массив.

array_merge(): Argument #1 is not an array

Я смотрел на эти другие интерфейсы, но ни один из них не кажется очевидным: IteratorAggregate, Сериализуемый, Счетный. Также ArrayObject оказался тупиком.

У меня есть геттер для преобразования в массив. Но я как бы прыгал, чтобы обнаружить, что мое $ object превращается в массив, просто реализуя ArrayAccess или Iterator, поскольку речь идет о развертывании массива.

Есть ли другой интерфейс, который я могу реализовать, чтобы сделать мой класс более похожим на массив?

2

Решение

Это новая языковая функция, как описано в руководство по миграции с 5.5.x до 5.6.x в руководстве (раздел Аргумент распаковывается через ...), вы должны быть на5.6.x во время выполнения.

Если вы не можете обновить вашу среду выполнения, вы должны использовать ваш геттер для преобразования его в массив (аналогично ArrayObject«s getArrayCopy):

call_user_func_array('array_merge', $arr->getArrayCopy());

тесты

Код ниже (на основе примеров документации PHP для ArrayAccess а также Iterator) успешно выполнен на PHP 5.6.2, 5.6.17 а также 7.0.1, Это действительно не удается на старых версиях (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]);
}
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]