如何从非控制器方法的方法发送响应?

时间:2016-07-24 17:32:22

标签: laravel laravel-5 laravel-5.2

我有一个Controller.php show($id)方法被路线击中。

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

    $this->checkEverythingIsOk($attributes);

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

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

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

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.
}

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

4 个答案:

答案 0 :(得分:6)

你可能正在寻找这个:

SELECT FileOne.[Tab$].Fields, FileTwo.[Tab$].Fields, etc.
    FROM FileOne, FileTwo, Thisworkbook
    WHERE (FileOne.[Tab$].field2 <> FileTwo.[Tab$].Field2) 
        AND (ThisWorkbook.[Tab$].Field1 ....)

在控制器方法中:

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
}

答案 1 :(得分:6)

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

没有必要将其作为控制器方法的返回值。

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

答案 2 :(得分:2)

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

// 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', ...);

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

更新

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

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

事实证明,已经内置于Laravel中的那些:

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

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

现在通常会记录一个Exception,如果你处于Debug模式,你会在屏幕上看到它等等。但是如果你在\Illuminate\Foundation\Exceptions\Handler方法中查看render可以看到,如果它是HttpResponseException的实例,它会检查抛出的异常。如果是,那么响应将立即返回。

答案 3 :(得分:0)

对我来说最简单优雅的方式是:

response()->json($messages_array, $status_code)->throwResponse();

(你不需要退货)

可以从私有函数或其他类调用...

我在辅助类中使用它来检查权限,如果用户没有权限,我会抛出上面的代码。