php / php/php-src

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

Abierto
#23,075 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Bug Category: Fibers Status: Verified
Lenguaje dominante
C
Estrellas
40.4k
Forks
8.2k
Merge medio
2 d 13 h
PR fusionados (30 d)
96

Descripción

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

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza con la reproducción proporcionada de fiber-magic-get.php y ejecútala con php -n; después, compara las salidas reales y esperadas. Investiga la protección contra la recursión de propiedades sobrecargadas entre los dos Fibers que comparten el objeto, incluidos los casos relacionados con __isset() y la coalescencia de null; se considera terminado cuando ambos accesos independientes invocan sus handlers y devuelven los valores esperados.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
php
Área
compilers
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Tranquilo
Claridad
Bastante claro
Aptitud para principiantes
48/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.