Использование объекта в качестве массива

StackOverflow https://stackoverflow.com/questions/2214397

  •  19-09-2019
  •  | 
  •  

Вопрос

В недавних обновлениях PHP они добавили различные интерфейсы, позволяющие обрабатывать объект как массив, такие как ArrayAccess, Iterator, Countable и т.д.

Мой вопрос в том, будет ли тогда иметь смысл, чтобы сработало следующее:

function useArray(array $array)
{
    print_r($array);
}

useArray(new ArrayObj(array(1,2,3,4,5));

На данный момент PHP выдает ошибку, указывающую на тип, поскольку $array технически это не массив.Однако он реализует все интерфейсы, что делает его в основном идентичным массиву.

echo $array[0]; // 1
$array[0] = 2;
echo $array[0]; // 2

По логике вещей, объект должен иметь возможность использоваться везде, где может быть использован массив, поскольку он реализует тот же интерфейс, что и массив.

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

Это было полезно?

Решение

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

Ан array это специальный тип переменной PHP - не объект - как таковой, он не реализует никаких интерфейсов. ArrayObject является полноценным объектом, реализующим множество интерфейсов (Countable, ArrayAccess, и т.д.) и позволяет объекту действовать как массив в определенных случаях (например, в цикле foreach).Таким образом, хотя они не реализуют одни и те же интерфейсы, они иногда веди себя так же.

Идеальным решением было бы, чтобы PHP поддерживал несколько сигнатур функций:

function useArray(array $array) { }
function useArray(ArrayObject $array) { }

Но пока мы не получим этого (если мы когда-нибудь получим это), вам просто нужно будет проверять типы переменных вне определения функции:

function useArray($array) {
 if (is_array($array) || $array instanceof ArrayObject) {
   // Do some stuff
 } else {
   throw new Exception('I require an array or an array-like structure!');
 }
}

Или попытаться сделать array-набирайте материал с помощью $array аргумент и обрабатывать любые предупреждения / ошибки, которые useArray может генерировать.

Другие советы

Ваш намек на тип указывает его тип "array", но ваша передача в "ArrayObj"

function useArray(array $array)
...
useArray(new ArrayObj

Так что да, он собирается жаловаться.

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

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

Просто потому, что два объекта реализуют один и тот же интерфейс, не означает, что они одного типа.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top