phpiterator

Why are objects considered not iterable although they actually are?


PHP 7.1 added the new is_iterable function to check whether a variable can be iterated. But although you may iterate over an objects properties is_iterable returns false for them.

This seems to be intentional, as it is documented and I couldn't find any PHP bugs regarding the issue but I wonder why this was done?

<?php
$a = new stdClass();
$a->foo = 'bar';

var_dump(is_iterable($a));

foreach ($a as $key => $value) {
    var_dump($key, $value);
}

Outputs

boolean false
string 'foo' (length=3)
string 'bar' (length=3)

But I would expect it to output

boolean true
string 'foo' (length=3)
string 'bar' (length=3)

Solution

  • Its a question of definition, and "why is it done" is a tricky question, probably better for the PHP devs.

    But some information: You can foreach over an object, and it will show the visible properies according to the manual

    PHP 5 provides a way for objects to be defined so it is possible to iterate through a list of items, with, for example a foreach statement. By default, all visible properties will be used for the iteration.

    The is_iterable is checking for specific things, see the manual

    Verify that the contents of a variable is accepted by the iterable pseudo-type, i.e. that it is an array or an object implementing Traversable

    An object does not implement Traversable if you don't do so yourself (and is not one of the 'other' things, like an array) so it is not "iterable" in that sence.

    Long story short: foreach can iterate over anything that is iterable, but not everything that foreach can iterate over is called iterable. Its a chair-has-4-legs vs everything-with-4-legs-is-a-chair kinda issue.

    I would see the fact that you can iterate over an object without explicitly implementing iterable is a sort of exception, and leave it at that. The only other anwer would be "they did it because".