2

例如这段代码

<?php
if (some_condition()) {
    header('Location: /');
    exit();
}

// do a lot of things...

在经典的 PHP FPM 上,以前的代码可以正常工作。但是在 PHP+Swoole 上,我们遇到了这个错误

swoole exit {"exception":"[object] (Swoole\\ExitException(code: 0): swoole exit at

错误是可以理解的。但是,迁移它的最简单方法是什么?

4

3 回答 3

2

对于 PHP FPM,每段代码都是单独执行的,结果(该过程的输出)通过管道传回客户端。因此,每当我们想停止处理时,我们只需触发exit().

但是,使用Swoole时,服务器应该一直运行。当然,可以使用 Swoole\Process::exit()停止进程- 但通常由控制器触发立即发送响应。例如:

$server = new Swoole\HTTP\Server("127.0.0.1", 9501);

$server->on("start", function (Swoole\Http\Server $server) {
    echo "Swoole http server is started at http://127.0.0.1:9501\n";
});

$server->on("request", function (Swoole\Http\Request $request, Swoole\Http\Response $response) {
    $response->header("Content-Type", "text/plain");
    $response->end("Hello World\n");
});

$server->start();

在这种情况下,$response->end该方法与 PHP FPM 世界中的功能基本相同exit()。请注意,这与 Node 世界中发生的情况非常相似:服务器应该一直在运行,而控制器(处理每个单独请求的函数)决定是否停止处理单独的请求并返回响应,包括标头和身体。

于 2021-07-03T23:56:22.603 回答
1

你可以了解一下\Swoole\ExitException

use Swoole\Coroutine;
use function Swoole\Coroutine\run;

function route()
{
    controller();
}

function controller()
{
    your_code();
}

function your_code()
{
    Coroutine::sleep(.001);
    exit(1);
}

run(function () {
    try {
        route();
    } catch (\Swoole\ExitException $e) {
        var_dump($e->getMessage());
        var_dump($e->getStatus() === 1);
        var_dump($e->getFlags() === SWOOLE_EXIT_IN_COROUTINE);
    }
});
于 2021-07-06T01:51:01.150 回答
0

如何exit()在 Laravel + Swoole 上替换

是的,这是一个非常糟糕的练习exit()功能。但是自己的 Laravel 应用程序会引导旧代码。然后,通过相关成本,这种方式是一个更好的解决方案。

  1. 做一个可渲染的异常
class ExitException extends Exception implements Renderable
{
    public function report() {
        return true; // dont report
    }

    public function render()
    {
        return ' '; // prevent 500 html dump error
    }
}
  1. 替换exit();
// exit;
throw new ExitException();

该异常将由您的应用程序错误处理程序处理,并向 Swoole 请求处理程序发送一个空字符串作为响应。

我再说一遍:这不是一个优雅的解决方案,只是防止在遗留应用程序上更改大量代码。

于 2021-07-04T19:45:23.007 回答