Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal to improve consistency of is_iterable() and isIterable Reflection class method with what foreach actually expects #10554

Open
wants to merge 3 commits into
base: PHP-8.1
Choose a base branch
from

Conversation

stalkonr
Copy link

@stalkonr stalkonr commented Feb 10, 2023

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

My setup

This happens on PHP 7.3, 8.1 and 8.2 (those that I tested on). I'm using Ubuntu 20.04

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!

Here is bug reported that I made: php/doc-en#2378

Best regards,
stalkonr

@stalkonr stalkonr changed the title Proposal to improve consitency of is_iterable() and isIterable Reflection class method with what foreach actually expects Proposal to improve consistency of is_iterable() and isIterable Reflection class method with what foreach actually expects Feb 10, 2023
…behaviours to what foreach expects: foreach() argument must be of type array|object, %s given
@stalkonr stalkonr force-pushed the stalkonr-improving-consistency-of-is-iterable-with-foearch-behaviour branch from 54a9a08 to 42640bc Compare February 10, 2023 11:45
@devnexen devnexen requested a review from arnaud-lb February 10, 2023 16:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants