当前位置: 首页 > 后端技术 > PHP

为什么Hyperf会关闭Swoole协程的简称

时间:2023-03-30 03:45:18 PHP

?在Hyperf官方文档的服务器要求中提到SwoolePHPextension>=4.5,并且关闭了ShortName。并且,在文档的FAQ中,你还会看到Swoole的简称不是Closethistag。请问,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')){/***@returnbool|int*/functiongo(callable$callable){$id=Coroutine::create($callable);}返回$id>0?$id:假的;}}如果是go()函数,会执行这里的逻辑调用Coroutine::create($callable)。注意这里的Coroutine类不是Swoole\Coroutine,而是vendor/hyperf/utils/src/Coroutine.phppublicstaticfunctioncreate(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)){/*@varLoggerInterface$logger*/$logger=$container->get(StdoutLoggerInterface::class);/*@varFormatterInterface$formatter*/if($container->has(FormatterInterface::class)){$formatter=$container->get(FormatterInterface::class);$logger->warning($formatter->format($throwable));}else{$logger->warning(sprintf('在%s::%d中检测到未捕获的异常[%s]。',get_class($throwable),$throwable->getFile(),$throwable->getLine()));}}}}});返回is_int($result)?$结果:-1;}可以看到,我们“劫持”了go()函数,对其进行了一些改动,捕获了创建的协程抛出的Exception,将异常打印到控制台(注意:对于Coroutine::create方法创建的协程,当callable中出现异常时会抛出Fatalerror,这是我们不希望看到的)。所以,到这里我们似乎明白为什么Hyperf要关闭Swoole这个简称了,目的就是劫持go()和co()函数来捕获可调用的异常,防止进程抛出Fatal错误

最新推荐
猜你喜欢