19

我有一个相对简单的功能,它使用foreach

function foo($t) {
     $result;
     foreach($t as $val) {
         $result = dosomething($result, $val);
     }
     return $result;
}

我想输入提示,并且Traversable似乎是我需要的确切类型提示

 function foo(Traversable $t) {

但是,这会E_RECOVERABLE_ERROR在使用数组时给出 a (当然可以在 a 中使用foreach):示例

 Argument 1 passed to foo() must implement interface Traversable, array given

有没有办法输入提示或者这是不可能的?

4

4 回答 4

23

PHP 7.1为此引入了iterable类型声明\Traversable,它接受数组和.

在以前的版本中,您必须省略类型声明。

于 2016-12-04T16:41:37.337 回答
8

有一个关于此的错误:#41942。关闭为“不是错误”。由于 PHP 数组不是对象,它们无法实现接口,因此无法同时键入提示arrayTraversable.

您可以使用iterator_to_arrayArrayIterator省略类型提示。请注意, 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);
于 2013-06-10T19:55:47.177 回答
4

同样的问题。我已经放弃了,我只是手动编写函数中的所有内容。

这应该为您提供所需的功能:

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)
       ));
    }
}
于 2013-11-19T06:11:10.050 回答
2

问题是,数组不是对象,所以它们不能实现接口。所以你不能同时输入提示arrayTraversable.

于 2013-06-10T19:58:07.350 回答