Skip to content

Switching coroutine contexts during autoload might causes Class "%s" not found error #5770

Open
@Appla

Description

@Appla

问题同#5180 , 是另一种情况

假定有 BasicObject.php

<?php

class BasicObject
{

}

Constant.php

<?php

class Constant extends BasicObject
{
    public const CONST_1 = 'PHP * Swoole',
}

不包含继承关系的类
SimpleConst.php

<?php

class SimpleConst
{
    public const GREETINGS = 'hello world';
}

test.php

<?php

\spl_autoload_register(static function ($clsName) {
    \Swoole\Coroutine::sleep(0.001);
    $path = __DIR__ . '/' . \str_replace('\\', '/', $clsName) . '.php';
    if (\is_file($path)) {
        require $path;
    } else {
        echo "class {$clsName} not found\n";
    }
});

function work_fn(...$args)
{
    echo SimpleConst::GREETINGS . PHP_EOL;
    \Swoole\Coroutine::sleep(\random_int(1, 5) / 1000);
    echo Constant::CONST_1 . PHP_EOL;
}

$closure = static fn() => work_fn();
$scheduler = new \Swoole\Coroutine\Scheduler();
for ($i = 0; $i < 16; ++$i) {
    $scheduler->add($closure, $i);
}
$scheduler->start();

执行可能会包含如下错误

PHP Fatal error:  Uncaught Error: Class "Constant" not found in /path/to/test.php:15
Stack trace:
#0 /path/to/test.php(20): work_fn()
#1 [internal function]: {closure}(1)
#2 {main}
  thrown in /path/to/test.php on line 15

测试从5.1.*~6.0.*都能复现
加载有继承关系的类时, 如有其他coroutine在类未加载完成时同时加载类就会遇到这个问题参考代码

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions