Laravel从私有方法重定向出现错误

pas*_*ert 5 php redirect if-statement laravel laravel-5

我有以下代码:

public function store(Request $request)
{
        $this->validateData($request->all());

        // store something

        return redirect()->action('controller@index')->withMessage( 'Saved Successfully' );
}

private function validateData($requestParams)
{
    try 
    {
        $validator->validate( $requestParams );
    } 
    catch ( ValidationException $e ) 
    {
        redirect()->action('controller@create')->withInput()->withErrors( $e->get_errors() )->send();
        exit(); // this causes the withErrors to not be there
    }
}
Run Code Online (Sandbox Code Playgroud)

如果删除exit();,将出现错误消息,但还会执行存储功能(请参阅参考资料// store something)。我知道我可以像这样重写我的代码:

if($this->validateData($request->all()))
{
    // store something

    return redirect()->action('controller@index')->withMessage( 'Saved Successfully' );
}
Run Code Online (Sandbox Code Playgroud)

但是我不想在if这里发表丑陋的说法。没有Flash消息,必须有一种重定向方法。

Hie*_* Le 5

tl; dr

像这样更新您的私有方法代码,以使重定向在$errors变量可见的情况下起作用:

private function validateData($requestParams)
{
    try 
    {
        $validator->validate( $requestParams );
    } 
    catch ( ValidationException $e ) 
    {
        $resp = redirect()->action('WelcomeController@index')->withInput()->withErrors($e->get_errors());
        \Session::driver()->save();
        $resp->send();
        exit();
    }
}
Run Code Online (Sandbox Code Playgroud)

解释

在控制器中间退出时,在应用程序终止中执行的某些作业将不再执行。在您的情况下,terminate将不会调用Session中间件方法。让我们看看它的内容(ref):

public function terminate($request, $response)
{
    if ($this->sessionHandled && $this->sessionConfigured() && ! $this->usingCookieSessions())
    {
        $this->manager->driver()->save();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,看看save我们的会话驱动程序(ref)的方法

public function save()
{
    $this->addBagDataToSession();
    $this->ageFlashData();
    $this->handler->write($this->getId(), $this->prepareForStorage(serialize($this->attributes)));
    $this->started = false;
}
Run Code Online (Sandbox Code Playgroud)

如您所见,仅在会话中间件成功终止时才保存闪存数据。使用您的旧代码,闪存数据将丢失!

我对代码所做的工作是save在将响应发送到浏览器之前手动调用该方法。但是,我仍然建议您将重定向带到公共控制器方法。