php / php/php-src

Magic property access skips __get() when another Fiber is suspended in __get() on the same object

Ouverte
#23,075 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Bug Category: Fibers Status: Verified
Langage dominant
C
Étoiles
40.4k
Forks
8.1k
Merge moyen
2 j 13 h
PR mergées (30 j)
96

Description

Description
Description

When two Fibers access the same undefined property on the same object, and the
first Fiber suspends inside __get(), the second Fiber does not invoke
__get().

Instead, PHP emits an "Undefined property" warning and returns null.
After the first Fiber is resumed, its property access returns the correct value.

The access from the second Fiber is not a recursive property access. It is an
independent access with its own Fiber execution stack.

The issue reproduces with php -n, without loading a php.ini or third-party
extensions.

Steps to reproduce

Save the following script as fiber-magic-get.php:

<?php

declare(strict_types=1);

final class YieldingProperty
{
    public function __get(string $name): int
    {
        Fiber::suspend();
        return 8;
    }
}

$value = new YieldingProperty();

$first = new Fiber(static function () use ($value): void {
    var_dump($value->property);
});

$second = new Fiber(static function () use ($value): void {
    var_dump($value->property);
});

$first->start();
$second->start();
$first->resume();

Run it without loading configuration or extensions:

php -n fiber-magic-get.php
Actual result
Warning: Undefined property: YieldingProperty::$property ...
NULL
int(8)

__get() is skipped for the second Fiber and the property access returns
null.

Expected result
int(8)
int(8)

Both property accesses should invoke __get() independently and return 8.

Suspending one Fiber inside __get() should not make an access from another
Fiber appear recursive.

Reproducibility

Always reproducible.

Tested with:

  • PHP 8.3.33 CLI on Linux, using php -n
  • PHP 8.4.7 CLI on Windows, using php -n
Additional information

The issue only occurs when the Fibers share the same object.

The following controls do not fail:

  • Giving each Fiber its own object
  • Replacing the magic property access with a normal method call on the shared
    object

The same problem also affects __isset() and null-coalescing property
expressions such as:

$value = $object->property ?? 0;

Under contention, these expressions can silently return the fallback value
even though __isset() returns true and __get() returns the expected value.

This behavior suggests that the recursion guard for overloaded properties is
associated with the shared object and remains visible to other Fibers while a
magic property handler is suspended.

PHP Version
PHP 8.3.33 (cli) (built: Jul 31 2026 12:56:07) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.33, Copyright (c) Zend Technologies
    with Zend OPcache v8.3.33, Copyright (c), by Zend Technologies

PHP 8.4.7 (cli) (built: May  6 2025 14:12:45) (ZTS Visual C++ 2022 x64)
Copyright (c) The PHP Group
Zend Engine v4.4.7, Copyright (c) Zend Technologies
Operating System

Windows 11, Plesk Linux ... 6.8.0-111-generic #111-Ubuntu SMP PREEMPT_DYNAMIC Sat Apr 11 23:16:02 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par la reproduction fournie de fiber-magic-get.php et exécutez-la avec php -n, puis comparez les sorties réelles et attendues. Étudiez la protection contre la récursion des propriétés surchargées entre les deux Fibers partageant le même objet, y compris les cas associés à __isset() et à la coalescence de null ; le travail est terminé lorsque les deux accès indépendants invoquent leurs handlers et renvoient les valeurs attendues.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
php
Domaine
compilers
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
Calme
Clarté
Plutôt claire
Accessibilité débutants
48/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.