Problem/Motivation

Using PHP 8.5, I get the following error message:

Deprecated function: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in Drupal\markdown\Annotation\AnnotationObject->getIterator() (line 245 of modules/contrib/markdown/src/Annotation/AnnotationObject.php).

Steps to reproduce

  1. Use PHP 8.5.
  2. Open Drupal's Status Report page.
CommentFileSizeAuthor
#3 3622983_3.patch532 byteslars.stiebenz

Issue fork markdown-3622983

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

lars.stiebenz created an issue. See original summary.

lars.stiebenz’s picture

The method of interest looks like this.

  public function getIterator(): \Traversable {
    $iterator = new \ArrayIterator($this);
    foreach ($this->_deprecated as $key => $value) {
      $iterator->offsetSet($key, $value);
    }
    return $iterator;
  }

As a workaround, you can convert the object to an array with get_object_vars():

  public function getIterator(): \Traversable {
    $iterator = new \ArrayIterator(get_object_vars($this));
    foreach ($this->_deprecated as $key => $value) {
      $iterator->offsetSet($key, $value);
    }
    return $iterator;
  }

Maybe someone with a better understanding of the use cases for the Iterator has a more elegant approach to fix this.

lars.stiebenz’s picture

StatusFileSize
new532 bytes

This patch is for those, who want to use the workaround for now.

orkutmuratyilmaz made their first commit to this issue’s fork.

orkutmuratyilmaz’s picture

Status: Active » Needs review

Thanks @lars.stiebenz for reporting this and for the workaround in #2/#3, it pointed straight at the cause.

I opened MR !66 with a slightly different fix. Called from inside the class, get_object_vars($this) also returns protected and private properties (class, provider, _deprecated, ...), and doMerge() then copies them from one definition to another. The MR reads the properties from a closure with no class scope instead, so the iterator still returns only the public properties, in the same order as before.

The new AnnotationObjectTest covers both points: iterating triggers no deprecation, and only the public properties are returned. On a PHP 8.5 site, the 35 rebuilt plugin definitions are identical with and without the change.