Skip to content

ForEach does not issue an error for non-iterable non-Traversable objects #4534

Open
@divinity76

Description

@divinity76

Description

The following code:

<?php
declare(strict_types=1);
error_reporting(E_ALL);
\set_error_handler(function ($errno, $errstr, $errfile, $errline) {
    if (\error_reporting() & $errno) {
        throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
    }
});
$a = ["foo" => "bar"];
$o = (object)$a;
$isIterable = is_iterable($o); // false
$isTraversable = $o instanceof Traversable; // false
var_dump(["isIterable" => $isIterable, "isTraversable" => $isTraversable]);
/*
Quoting https://www.php.net/manual/en/control-structures.foreach.php
The foreach construct provides an easy way to iterate over arrays and Traversable objects.
>>>foreach will issue an error when used with a variable containing a different data type<<<
*/
foreach ($o as $key => $val) {
    var_dump(["key" => $key, "val" => $val]);
}
?>

Resulted in this output:

array(2) {
  ["isIterable"]=>
  bool(false)
  ["isTraversable"]=>
  bool(false)
}
array(2) {
  ["key"]=>
  string(3) "foo"
  ["val"]=>
  string(3) "bar"
}

But given the ForEach documentation, I expected this output instead:

array(2) {
  ["isIterable"]=>
  bool(false)
  ["isTraversable"]=>
  bool(false)
}
Fatal error: Uncaught TypeError: ForEach: Argument php/php-src#1 (iterable_expression) must be iterable or instance of Traversable

(some variant of that)

So it seems either the documentation or the implementation is wrong here.

PHP Version

PHP 8.4.5

Operating System

Ubuntu24.04

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions