Php 来自私有方法的Laravel重定向出现错误
我有以下代码:Php 来自私有方法的Laravel重定向出现错误,php,laravel,redirect,if-statement,laravel-5,Php,Laravel,Redirect,If Statement,Laravel 5,我有以下代码: public function store(Request $request) { $this->validateData($request->all()); // store something return redirect()->action('controller@index')->withMessage( 'Saved Successfully' ); } private function v
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
}
}
如果我删除exit()代码>,将显示错误消息,但也将执行存储功能(请参见//存储内容
)。我知道我可以像这样重写代码:
if($this->validateData($request->all()))
{
// store something
return redirect()->action('controller@index')->withMessage( 'Saved Successfully' );
}
但是我不想要这里丑陋的if
语句。必须有一种方法可以在没有它的情况下重定向flash消息。我认为使用if语句没有任何问题。基本上,您不会停止代码执行,因此即使验证失败,也会执行存储函数。重定向函数只发送一个带有重定向位置的头,它不会在执行代码后中止代码。它使用exit()
,因为它发送重定向头并停止要执行的其余代码
这并不难看,它干净清晰,我建议你用这个。这是右if
语句用法的一个很好的例子-如果我满足一个条件,那么就这样做。在您的情况下,如果验证通过,只需存储对象即可。(请记住修改validate函数以返回true或false)
另一种可能的解决方案是使用try。。捕捉
这样的块
public function store(Request $request)
{
try {
$this->validateData($request->all());
// store something
return redirect()->action('controller@index')->withMessage( 'Saved Successfully' );
} catch ( ValidationException $e ) {
return redirect()->action('controller@create')->withInput()->withErrors( $e->get_errors() );
}
}
private function validateData($requestParams)
{
// Your validation logic here
$validator->validate( $requestParams );
}
您只是在验证异常D之后忘记了“return”,那么您就不必“exit;” tl;博士
像这样更新您的私有方法代码,使重定向在$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();
}
}
解释
当您在控制器的中间退出时,在应用程序终止中执行的某些作业将不再执行。在您的情况下,将不会调用会话中间件
terminate
方法。让我们看看它的内容():
现在,看看会话驱动程序()的save
方法
如您所见,只有当会话中间件成功终止时,才会保存闪存数据。使用旧代码,闪存数据将丢失
我对代码所做的是在将响应发送到浏览器之前手动调用save
方法。但是,我仍然建议您将重定向带到public controller方法。然后它仍然执行//存储某些内容
,我认为这可能是因为您重定向到错误的操作(需要POST请求的操作)。也许是controller@create“-该方法负责处理POST数据吗?不,一切正常。返回只会返回并执行//存储一些东西
。哦,我明白了-我完全误解了你,这是当之无愧的负:D。实际上我不知道如何避免使用“If”语句。您可以检查所有流行的Laravel代码库——它们坚持使用“if”语句来检查验证。下面是一个例子,如果你再次调用私有函数中的私有函数,情况会变得很糟糕。您需要在每个函数中执行if语句,然后得到一个if语句链..好的,我稍后会尝试一下。在我的午餐休息时间。从逻辑上看,解决方案属于答案,而不属于问题。请记住,这是一个问答网站。
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();
}
}
public function terminate($request, $response)
{
if ($this->sessionHandled && $this->sessionConfigured() && ! $this->usingCookieSessions())
{
$this->manager->driver()->save();
}
}
public function save()
{
$this->addBagDataToSession();
$this->ageFlashData();
$this->handler->write($this->getId(), $this->prepareForStorage(serialize($this->attributes)));
$this->started = false;
}