关于php:Hyperf为什么要关闭Swoole协程短名称

54次阅读

共计 1686 个字符,预计需要花费 5 分钟才能阅读完成。

在 Hyperf 官网文档的服务器要求中提到

Swoole PHP 扩大 >= 4.5,并敞开了 Short Name

并且,在文档的常见问题中也会看到 Swoole 短名未敞开这一个 tag。

我想问了,那为什么 hyperf 肯定要敞开掉 Swoole 的协程短名称呢

首先,咱们先看一下什么是 Swoole 的协程短名称

所有的 Swoole\Coroutine 前缀的类名映射为 Co。此外还有上面的一些映射:创立协程 go() 函数,通道操作 chan() 函数,提早执行 defer() 函数

从下面的解释咱们晓得了,hyperf 次要就是不想让咱们应用以上这几个函数,然而为啥不让咱们应用的呢?想到之前在代码中常常应用 go() 函数来解决代码中的阻塞问题,难道说我写的代码并没有协程化?在 Hyperf 通过测试之后发现,go() 函数协程话的确是失效的,那到底是什么让原本曾经被禁用的 go() 函数又“复活”了呢?

在 phpStrom 只点击 go() 函数咱们跳转到了 vendor/hyperf/utils/src/Functions.php 文件,该文件是在 composer.json 中指定的自动化加载文件

if (! function_exists('go')) {
    /**
     * @return bool|int
     */
    function go(callable $callable)
    {$id = Coroutine::create($callable);
        return $id > 0 ? $id : false;
    }
}

如果框架里没定义 go() 函数的话,就会执行这里的逻辑去调用 Coroutine::create($callable),留神这里的 Coroutine 类并不是 Swoole\Coroutine,而是 vendor/hyperf/utils/src/Coroutine.php

public static function create(callable $callable): int
    {$result = SwooleCoroutine::create(function () use ($callable) {
            try {call($callable);
            } catch (Throwable $throwable) {if (ApplicationContext::hasContainer()) {$container = ApplicationContext::getContainer();
                    if ($container->has(StdoutLoggerInterface::class)) {
                        /* @var LoggerInterface $logger */
                        $logger = $container->get(StdoutLoggerInterface::class);
                        /* @var FormatterInterface $formatter */
                        if ($container->has(FormatterInterface::class)) {$formatter = $container->get(FormatterInterface::class);
                            $logger->warning($formatter->format($throwable));
                        } else {$logger->warning(sprintf('Uncaptured exception[%s] detected in %s::%d.', get_class($throwable), $throwable->getFile(), $throwable->getLine()));
                        }
                    }
                }
            }
        });
        return is_int($result) ? $result : -1;
    }

能够看到,咱们“劫持”了 go() 函数,给他做了一些改变,捕捉了创立协程时抛出的异样,将异样打印到管制台上。(注:对于 Coroutine::create 形式创立的协程在 callable 中存在异样时会抛出 Fatal error,这是咱们不违心看到的)。

所以,到这里咱们仿佛了解了为什么 Hyperf 要敞开 Swoole 的短名称,目标就是劫持 go()、co() 函数来捕捉 callable 的异样防止过程抛出 Fatal error

正文完
 0