laravel 如何从不是控制器方法的方法发送响应?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38554809/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 14:12:25  来源:igfitidea点击:

How to send a response from a method that is not the controller method?

laravellaravel-5laravel-5.2

提问by dazedviper

I've got a Controller.phpwhose show($id)method is hit by a route.

我有一个Controller.php,其show($id)方法是通过路由击中。

public function show($id)
{
    // fetch a couple attributes from the request ...

    $this->checkEverythingIsOk($attributes);

    // ... return the requested resource.
    return $response;
}

Now, in checkEverythingIsOk(), I perform some validation and authorization stuff. These checks are common to several routes within the same controller, so I'd like to extract these checks and call the method everytime I need to perform the same operations.

现在,在 中checkEverythingIsOk(),我执行一些验证和授权操作。这些检查对于同一控制器内的多个路由是通用的,因此我想提取这些检查并在每次需要执行相同操作时调用该方法。

The problem is, I'm unable to send some responses from this method:

问题是,我无法通过此方法发送一些响应:

private function checkEverythingIsOk($attributes)
{
    if (checkSomething()) {
        return response()->json('Something went wrong'); // this does not work - it will return, but the response won't be sent.
    }

    // more checks...
    return response()->callAResponseMacro('Something else went wrong'); // does not work either.

    dd($attributes); // this works.
    abort(422); // this works too.
}

Note:Yes, I know in general one can use middleware or validation services to perform the checks before the request hits the controller, but I don't want to. I need to do it this way.

注意:是的,我知道通常可以使用中间件或验证服务在请求到达控制器之前执行检查,但我不想这样做。我需要这样做。

采纳答案by Voyowsky

You are probably looking for this:

你可能正在寻找这个:

function checkEverythingIsOk(){
    if (checkSomething()) {
        return Response::json('Something went wrong', 300);
    }
    if(checkSomethingElse()) {
        return Response::someMacro('Something else is wrong')
    }
    return null; // all is fine
}

And in the controller method:

在控制器方法中:

$response = $this->checkEverythingIsOk();
if(!is_null($response)) {
    return $response;
}

回答by Boris D. Teoharov

As of Laravel 5.6 you can now use for example response()->json([1])->send();.

从 Laravel 5.6 开始,您现在可以使用例如response()->json([1])->send();.

There is no need for it to be the return value of a controller method.

它不需要是控制器方法的返回值。

Note that calling send()will not terminate the output. You may want to call exit;manually after send().

请注意,调用send()不会终止输出。您可能想在exit;之后手动调用send()

回答by mwallisch

It's probably overkill, but I will throw it in anyway. You might want to look into internal requests. Also this is just pseudoish code, I have not actually done this, so take this bit of information with caution.

这可能有点矫枉过正,但无论如何我都会把它扔进去。您可能想查看内部请求。此外,这只是伪代码,我实际上并没有这样做,所以请谨慎使用这些信息。

// build a new request
$returnEarly = Request::create('/returnearly');

// dispatch the new request
app()->handle($newRequest);

// have a route set up to catch those
Route::get('/returnearly', ...);

Now you can have a Controller sitting at the end of that route and interpret the parameters, or you use multiple routes answered by multiple Controllers/Methods ... up to you, but the approach stays the same.

现在,您可以在该路由的末尾放置一个控制器并解释参数,或者您可以使用由多个控制器/方法回答的多个路由......由您决定,但方法保持不变。

UPDATE

更新

Ok I just tried that myself, creating a new request and dispatching that, it works this way. Problem is, the execution does not stop after the child-request has exited. It goes on in the parent request. Which makes this whole approach kind of useless.

好的,我只是自己尝试过,创建一个新的请求并发送它,它是这样工作的。问题是,子请求退出后执行不会停止。它在父请求中继续。这使得整个方法有点无用。

But I was thinking about another way, why not throw an Exception and catch it in an appropriate place to return a specified response?

但是我在想另一种方式,为什么不抛出异常并在适当的地方捕获它以返回指定的响应?

Turns out, thats already built into Laravel:

事实证明,这已经内置在 Laravel 中:

// create intended Response
$response = Response::create(''); // or use the response() helper

// throw it, it is a Illuminate\Http\Exception\HttpResponseException
$response->throwResponse();  

Now usually an Exception would be logged and you if you are in Debug mode, you would see it on screen etc. etc. But if you take a look into \Illuminate\Foundation\Exceptions\Handlerwithin the rendermethod you can see that it inspects the thrown Exception if it is an instance of HttpResponseException. If it is then the Response will be returned immediately.

现在通常一个异常将被记录和你,如果你是在调试模式下,你会看到它在屏幕上等等等等。但是,如果你看看到\Illuminate\Foundation\Exceptions\Handler的内render方法,你可以看到它检查抛出的异常,如果它是一个实例的HttpResponseException。如果是,则 Response 将立即返回。