Intereting Posts

Подсказка PHP Traversable type

У меня есть относительно простая функция, которая использует 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 не являются объектами, они не могут реализовать интерфейс и, таким образом, нет способа набрать hint как 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 .