PHP Traversable type hint

Deadly 提交于 2019-12-18 18:49:55

问题


I have a relatively simple function which uses a foreach

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

I would like to type hint, and Traversable seems to be the exact type hint I need

 function foo(Traversable $t) {

However this gives a E_RECOVERABLE_ERROR when using an array (which is of course usable in a foreach): example

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

Is there a way to type hint or is this not possible?


回答1:


PHP 7.1 introduces the iterable type declaration for this purpose, which accepts both arrays and instances of \Traversable.

In previous versions, you'll have to omit the type declaration.




回答2:


There is a bug about this: #41942. Closed as 'not a bug'. As PHP arrays are not objects they cannot implement an interface and a such there is no way to type hint both array and Traversable.

You can use iterator_to_array, ArrayIterator or omit the type hint. Note that iterator_to_array will copy the whole iterator into an array an might thus be inefficient.

// 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);



回答3:


Same problem. I've given up I simply manually code everything in the function.

This should give you the functionality you want:

function MyFunction($traversable)
{
    if(!$traversable instanceof Traversable && !is_array($traversable))
    {
        throw new InvalidArgumentException(sprintf(
            'Myfunction($traversable = %s): Invalid argument $traversable.'
            ,var_export($traversable, true)
       ));
    }
}

EDIT

If you only want to display type of $traversable. And if you want the functionality inheritable in child classes.

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)
       ));
    }
}



回答4:


The problem is, that arrays are no objects, so they can't implement an interface. So you can't type hint both, array and Traversable.



来源:https://stackoverflow.com/questions/17031720/php-traversable-type-hint

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!