php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #77864 ArrayObject->getIterator not working in PHP 7.4 snapshot?
Submitted: 2019-04-08 17:32 UTC Modified: 2019-04-08 17:58 UTC
From: jay at diablomedia dot com Assigned:
Status: Not a bug Package: Arrays related
PHP Version: master-Git-2019-04-08 (snap) OS: Linux
Private report: No CVE-ID: None
 [2019-04-08 17:32 UTC] jay at diablomedia dot com
Description:
------------
I first noticed this in this test suite on travis running on the php7.4-snapshot that's available on Travis (I believe this is a nightly snapshot of the 7.4 branch):

https://travis-ci.org/diablomedia/zf1-controller/jobs/517348370

There are two tests that fail there due to `get_class` trying to operate on a boolean rather than on a class (these tests pass fine in all versions prior to 7.4).

Looking at the code a bit, I've been able to narrow the failure down to a simple script that I've added to the "Test script" section of this bug (also on 3v4l.org: https://3v4l.org/KZg3c).

In all versions prior to PHP 7.4, this will output `int(1)` in PHP 7.4 it outputs `bool(false)`.

Here's output from `php --version` in the docker container I was testing this on locally:

docker run -it --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp tommymuehle/docker-alpine-php-nightly php --version
PHP 8.0.0-dev (cli) (built: Feb 11 2019 05:57:53) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.0-dev, Copyright (c) Zend Technologies

(seems that container is on the php 8.0 branch (dev-master I assume), but based on the travis failures I'm fairly certain the same issue exists on the current php 7.4 snapshot as well)



Test script:
---------------
<?php

$array = [1,2,3];

$iterator = (new ArrayObject($array))->getIterator();

var_dump(current($iterator));

Expected result:
----------------
`int(1)`

Actual result:
--------------
`bool(false)`

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-04-08 17:56 UTC] requinix@php.net
-Summary: ArrayObject->getIterator not working in PHP 7.4 snapshot? +Summary: current(ArrayIterator) not working in PHP 7.4 snapshot -Status: Open +Status: Verified
 [2019-04-08 17:56 UTC] requinix@php.net
Yes, master is 8.0 while 7.4 is a branch, done so that some planned 8.0-only changes can start going in without affecting 7.4.

I believe it's currently undefined behavior to use current/key on an iterator that has not been reset yet, so the code should be doing that first.
  $iterator = $this->stack->getIterator();
  reset($iterator);
But that does not fix the problem - at least as far as the test script is concerned.

Looks like it's not just current() but all the others too. Surely all the same single underlying bug. Calling them directly like $iterator->current() does work.
 [2019-04-08 17:58 UTC] nikic@php.net
-Summary: current(ArrayIterator) not working in PHP 7.4 snapshot +Summary: ArrayObject->getIterator not working in PHP 7.4 snapshot? -Status: Verified +Status: Not a bug
 [2019-04-08 17:58 UTC] nikic@php.net
current() and friends do **not** work on Iterators, they work on arrays and the internal array pointer. When applied to objects current() etc iterate over the properties of the object.

Prior to PHP 7.4 current() etc did work on ArrayIterator specifically (but no other Iterators) due to an implementation quirk, but this is no longer supported.

This change is documented in the upgrading guide at https://github.com/php/php-src/blob/07df6594b5c71b176b376aba8007bc33616bbfb0/UPGRADING#L75-L86. The portable solution is to replace current($iterator) with $iterator->current().
 [2019-04-08 18:40 UTC] jay at diablomedia dot com
Thanks for the update and the explanation of the change.  Will update code where necessary.
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Mon Mar 30 13:01:25 2020 UTC