Magic property access skips __get() when another Fiber is suspended in __get() on the same object
还没有人认领这个 Issue。
- 主要语言
- C
- 星标
- 40.4k
- 派生
- 8.1k
- 平均合并
- 2 天 13 小时
- 30 天内合并 PR
- 96
描述
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
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
从提供的 fiber-magic-get.php 复现开始,使用 php -n 运行它,然后比较实际输出和预期输出。调查两个共享对象的 Fibers 之间 overloaded property 的递归保护机制,包括相关的 __isset() 和 null 合并情况;当两个独立访问都调用各自的 handler 并返回预期值时,即表示完成。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- php
- 领域
- compilers
- Issue 类型
- 缺陷
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 活跃度
- 冷清
- 描述清晰度
- 基本清楚
- 新手友好度
- 48/100