php / php/php-src

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

Aperta
#23,075 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Bug Category: Fibers Status: Verified
Lingua principale
C
Stelle
40.4k
Fork
8.1k
Merge medio
2g 13h
PR unite (30g)
96

Descrizione

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

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia con la riproduzione fornita di fiber-magic-get.php ed eseguila con php -n, quindi confronta gli output effettivi e quelli attesi. Analizza la protezione dalla ricorsione delle proprietà sovraccaricate tra i due Fibers che condividono l'oggetto, inclusi i casi correlati a __isset() e alla coalescenza dei null; il lavoro è completato quando entrambi gli accessi indipendenti invocano i rispettivi handler e restituiscono i valori attesi.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
php
Ambito
compilers
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Tranquilla
Chiarezza
Abbastanza chiara
Idoneità per principianti
48/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.