我在Laravel控制器中使用Post/Redirect/Get (PRG)模式来防止重复提交表单。
当我不使用布局或布局不使用任何变量时,它很有效。问题是我的布局使用了一个名为$title
的变量。当我加载视图和没有重定向的布局时,它运行良好,控制器中的标题集传递给布局,但在处理表单并重定向到使用相同布局和相同控制器方法的相同路径后,我得到一个来自我的布局文件的“未定义变量:标题”错误。
这是我的代码:
文件:app / routes.php
Route::get('contact', array('as' => 'show.contact.form', 'uses' => 'HomeController@showContactForm'));
Route::post('contact', array('as' => 'send.contact.email', 'uses' => 'HomeController@sendContactEmail'));
文件:app / controllers / HomeController.php
class HomeController extends BaseController {
protected $layout = 'layouts.master';
public function showContactForm()
{
$this->layout->title = 'Contact form';
$this->layout->content = View::make('contact-form');
}
public function sendContactEmail()
{
$rules = ['email' => 'required|email', 'message' => 'required'];
$input = Input::only(array_keys($rules));
$validator = Validator::make($input, $rules);
if($validator->fails())
return Redirect::back()->withInput($input)->withErrors($validator);
// Code to send email omitted as is not relevant
Redirect::back()->withSuccess('Message sent!');
}
}
文件:app / views / layouts / master.blade.php
<!DOCTYPE html>
<html>
<head>
<title>{{{ $title }}}</title>
</head>
<body>
@yield('body')
</body>
</html>
文件:app / views / contact-form.blade.php
@section('body')
@if (Session::has('success'))
<div class="success">{{ Session::get('success') }}</div>
@endif
{{
Form::open(['route' => 'send.contact.email']),
Form::email('email', null, ['placeholder' => 'E-mail']),
Form::textarea('message', null, ['placeholder' => 'Message']),
Form::submit(_('Send')),
Form::close()
}}
@stop
我不明白为什么在重定向下一行代码后会被忽略
$this->layout->title = 'Contact form';
我尝试使用Redirect::action('HomeController@sendContactEmail');
或Redirect::route('show.contact.form');
,但结果是一样的。
负责呈现该视图的控制器在重定向之前与重定向之后完全相同,并且它根本没有业务逻辑,那么为什么它只适用于第一种情况但不适用于第二种情况?
答案 0 :(得分:1)
此
Redirect::back()->withSuccess('Message sent!');
应该是
return Redirect::back()->withSuccess('Message sent!');
在控制器中设置layout
属性且方法未返回任何响应时,控制器会尝试呈现layout
。在sendContactEmail()
方法中,两个条件都已完成,控制器尝试在设置$title
之前渲染布局。
请参阅callAction()
中的Illuminate\Routing\Controllers\controller
。
http://laravel.com/api/source-class-Illuminate.Routing.Controllers.Controller.html#93-127
答案 1 :(得分:0)
您是否尝试过使用
return View::make('contact-form', array('title' => 'Contact Form'));
而不是直接与布局交互?
答案 2 :(得分:0)
Redirect :: back()使用当前HTTP请求的referer值创建302。我首先将初始表单请求与重定向请求进行比较,看看是否会产生任何线索。你也可以试试......
Redirect::route('HomeController@showContactForm')->withInput()...
我知道它不那么动态,但它会生成URL,而不是依赖于HTTP头中的referer值。