Skip to content

Inconsistency of is_iterable() and isIterable Reflection class method with what foreach actually expects #2378

Open
@stalkonr

Description

@stalkonr

Description

What I did?

Basically I have json_decode object, which contains key value configuration (which comes from API), like this

  $var = [
	  'key1' => 'value1',
	  'key2' => 'value2',
	  'key3' => 'value3'
  ];
  
  $object = json_decode(json_encode($var));

and I want to iterate over those key values with foreach:

foreach ($object as $key => $value) {
	echo $key;
}

which works fine. However, I want to guard this foreach from iterating on improper values. That's why I used is_iterable() (https://www.php.net/manual/en/function.is-iterable.php), In PHP RFC: Iterable (https://wiki.php.net/rfc/iterable) we can read:

It is common for a function to accept or return either an array or an object implementing Traversable to be used with foreach. However, because array is a primitive type and Traversable is an interface, there currently is no way to use a type declaration on a parameter or return type to indicate that the value is iterable.

What I wanted to happen?

I wanted that is_iterable would guard my foreach from every wrong value, like false, null and would allow object like above. See example:

  $var = [
	  'key1' => 'value1',
	  'key2' => 'value2',
	  'key3' => 'value3'
  ];
  
  $object = json_decode(json_encode($var));
  
  if (is_iterable($object) {
    foreach ($object as $key => $value) {
	echo $key;
    }
  }

What actually happened?

It turned that above object passed to is_iterable() returns false, which suprise me because it can be perfectlly fined passed to foreach, which has this warning if you pass something expected:

foreach() argument must be of type array|object, %s given

Summary

My PR propose to fix this inconsistency (or at least in my opinion it's inconsistency).

Please take a look and let me know what do you think, thanks!

Best regards,
stalkonr

PHP Version

8.1

Operating System

Ubuntu 20.04

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions