I have a relatively simple function which uses a foreach
function foo($t) {
$result;
foreach($t as $val) {
$result = dosometh
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);
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)
));
}
}
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.
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
.