🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 退出协程 [TOC] > 在Swoole低版本中, 协程中使用exit强行退出脚本会导致内存错误导致不可预期的结果或coredump, 在Swoole服务中使用exit会使整个服务进程退出且内部的协程全部异常终止导致严重问题 > > Swoole长期以来一直禁止开发者使用exit, 但开发者可以使用抛出异常这种非常规的方式, 在顶层catch来实现和exit相同的退出逻辑 > > 4.2.2版本及以上允许脚本(未创建http\_server)在只有当前协程的情况下exit退出 Swoole**`4.1.0`**版本及以上直接支持了在`协程`,`服务事件循环`中使用PHP的`exit`, 此时底层会自动抛出一个可捕获的`Swoole\ExitException`, 开发者可以在需要的位置捕获并实现与原生PHP一样的退出逻辑. * * * `Swoole\ExitException`继承于`Exception`且新增了两个方法`getStatus`和`getFlags`: ## 类原型: ~~~ namespace Swoole; class ExitException extends \Exception { public function getStatus():mixed public function getFlags():int } ~~~ ## 函数原型 ~~~ public function getStatus():mixed ~~~ 获取exit($status)退出时的传入的`status`参数, 支持任意的变量类型 ~~~ public function getFlags():int ~~~ 获取exit退出时所处的环境信息掩码, 目前有以下掩码 ~~~ SWOOLE_EXIT_IN_COROUTINE //协程中退出 SWOOLE_EXIT_IN_SERVER //服务中退出 ~~~ ## 使用方法 #### 基本使用 ~~~ function route() { controller(); } function controller() { your_code(); } function your_code() { co::sleep(.001); exit(1); } go(function () { try { route(); } catch (\Swoole\ExitException $e) { assert($e->getStatus() === 1); assert($e->getFlags() === SWOOLE_EXIT_IN_COROUTINE); return; } }); ~~~ #### 带状态码的退出 ~~~ <?php $exit_status = 0; go(function () { try { exit(123); } catch (\Swoole\ExitException $e) { global $exit_status; $exit_status = $e->getStatus(); } }); swoole_event_wait(); exit($exit_status); ~~~ #### 关闭内置协程, 允许在异步中退出 ~~~ swoole_async_set([ 'enable_coroutine' => false ]); swoole_timer_after(1000, function () { exit; }); ~~~