简体   繁体   English

如何在 swoole 上做一个经典的 php exit()?

[英]How to do a classic php exit() on swoole?

For example this code例如这个代码

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

// do a lot of things...

On classic PHP FPM previous code works fine.在经典的 PHP FPM 上,以前的代码工作正常。 But on PHP+Swoole, we ge this error但是在 PHP+Swoole 上,我们得到这个错误

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

The error is understandable.错误是可以理解的。 But, what is the easiest way to migrate it?但是,迁移它的最简单方法是什么?

For PHP FPM, each piece of code was executed individually, and the result (output of that process) was piped back to a client.对于 PHP FPM,每段代码都单独执行,结果(该过程的输出)通过管道返回给客户端。 So whenever we wanted to stop processing, we just triggered exit() .所以每当我们想停止处理时,我们只需触发exit()

With Swoole , however, the server is expected to run all the time.然而,使用Swoole时,服务器预计会一直运行。 Sure, it's possible to stop the Process with Swoole\\Process::exit() - but it's usually up to controller's to trigger sending the response immediately.当然,可以使用 Swoole\\Process::exit()停止进程- 但通常由控制器来触发立即发送响应。 For example:例如:

$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();

In this case, $response->end is the method that does essentially the same thing as exit() in PHP FPM world.在这种情况下, $response->end是与 PHP FPM 世界中的exit()基本相同的方法。 Note that it's quite similar to what happens in Node world: the server is expected to be running all the time, and it's the controllers (functions processing each individual request) deciding whether to stop handling individual request and pass back the response, both headers and body.请注意,它与 Node 世界中发生的情况非常相似:服务器应该一直运行,并且由控制器(处理每个单独请求的函数)决定是否停止处理单个请求并传回响应,包括标头和身体。

How to replace exit() on Laravel + Swoole如何在 Laravel + Swoole 上替换exit()

Yes, its a very bad practice exit() function.是的,这是一个非常糟糕的做法exit()函数。 But own Laravel app bootstrap a Legacy code.但是自己的 Laravel 应用程序会引导一个旧代码。 Then, by associated costs, its a better solution this way.然后,通过相关成本,它是一种更好的解决方案。

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

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

That exception will be handled by your app Error Handler, and send an empty string as response to Swoole request handler.该异常将由您的应用程序错误处理程序处理,并向 Swoole 请求处理程序发送一个空字符串作为响应。

I repeat: IS NOT AN ELEGANT SOLUTION, just prevent change a lot of code on legacy app.我再说一遍:不是一个优雅的解决方案,只是防止更改遗留应用程序上的大量代码。

You can learn about \\Swoole\\ExitException .您可以了解\\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);
    }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM