Ответ 1
PHP 7.1 вводит iterable
объявление типа для этой цели, которая принимает как массивы, так и экземпляры \Traversable
.
В предыдущих версиях вам придется опустить объявление типа.
У меня есть относительно простая функция, которая использует foreach
function foo($t) {
$result;
foreach($t as $val) {
$result = dosomething($result, $val);
}
return $result;
}
Я хотел бы набрать подсказку, и Traversable
кажется точной подсказкой типа Мне нужно
function foo(Traversable $t) {
Однако это дает E_RECOVERABLE_ERROR
при использовании массива (который, конечно, можно использовать в foreach
): пример
Argument 1 passed to foo() must implement interface Traversable, array given
Есть ли способ набрать подсказку или это невозможно?
PHP 7.1 вводит iterable
объявление типа для этой цели, которая принимает как массивы, так и экземпляры \Traversable
.
В предыдущих версиях вам придется опустить объявление типа.
Есть ошибка об этом: # 41942. Закрыто как "не ошибка". Поскольку массивы PHP не являются объектами, они не могут реализовать интерфейс и, таким образом, нет способа набрать подсказку как array
, так и Traversable
.
Вы можете использовать iterator_to_array
, ArrayIterator
или опустить подсказку типа. Обратите внимание, что iterator_to_array скопирует весь итератор в массив, поэтому может быть неэффективным.
// These functions are functionally equivalent but do not all accept the same arguments
function foo(array $a) { foobar($a); }
function bar(Traversable $a) { foobar($a); }
function foobar($a) {
foreach($a as $key => $value) {
}
}
$array = array(1,2,3)
$traversable = new MyTraversableObject();
foo($array);
foo(iterator_to_array($traversable));
bar(new ArrayIterator($array));
bar($traversable);
foobar($array);
foobar($traversable);
Такая же проблема. Я отказался от всего, что я просто вручную кодировал в функции.
Это даст вам необходимую функциональность:
function MyFunction($traversable)
{
if(!$traversable instanceof Traversable && !is_array($traversable))
{
throw new InvalidArgumentException(sprintf(
'Myfunction($traversable = %s): Invalid argument $traversable.'
,var_export($traversable, true)
));
}
}
ИЗМЕНИТЬ
Если вы хотите отобразить только тип $traversable
. И если вы хотите, чтобы функциональность наследовалась в дочерних классах.
public function MyMethod($traversable)
{
if(!$traversable instanceof Traversable && !is_array($traversable))
{
throw new InvalidArgumentException(sprintf(
'%s::MyMethod($traversable): Invalid argument $traversable of type `%s`.'
,get_class($this)
,gettype($traversable)
));
}
}
Проблема заключается в том, что массивы не являются объектами, поэтому они не могут реализовать интерфейс. Поэтому вы не можете набирать подсказки как array
, так и Traversable
.