我使用laravel已经好几个月了,但从未遇到过这样的问题。
我制作了一个简单的Request类来验证更新用户请求,如果遵循验证规则,它就可以正常工作。如果验证规则失败,我们应该返回到上一页,并在html中显示所有错误。
据我说,我已经像以前在其他应用程序中一样正确地编写了所有内容,但$errors
在刀片中似乎无法访问
以下是我需要调试的代码片段:
routes.php
Route::group(['middleware' => ['web']], function () {
Route::get('/users/{id}/edit', 'UserController@edit');
Route::post('/users/{id}/edit', 'UserController@update');
});
UserController.php
<?php
namespace App'Http'Controllers;
use Illuminate'Http'Request;
use App'Http'Requests;
use App'Http'Requests'UserUpdateRequest;
use App'Models'User;
use App'Models'Role;
use App'Models'Post;
class UserController extends Controller
{
public function edit($id)
{
try {
$user = User::find($id);
$roles = Role::all();
return view('users.edit', compact(['user', 'roles']));
}catch(Exception $e) {
return view('errors.500', compact(['e']));
}
}
public function update($id, UserUpdateRequest $request)
{
dd($request);
}
}
UserUpdateRequest.php
<?php
namespace App'Http'Requests;
use App'Http'Requests'Request;
class UserUpdateRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required|string|min:4',
'email' => 'required|email',
'role' => 'required|numeric',
'password' => 'required',
];
}
}
edit.blade.php
@extends('master')
@section('title') Edit Users @stop
@section('content')
<div class="row">
<div class="col-sm-12">
<h2>Edit User</h2>
</div>
</div>
<div class="alert alert-warning alert-dismissible" role="alert">
@foreach($errors->all() as $error)
{{ $error }}
@endforeach
</div>
<form action="{{ url('/users/'.$user->id.'/edit') }}" method="post">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<div class="col-sm-6">
<div class="form-group">
<label>Name</label>
<input type="text" name="name" value="{{ $user->name }}" class="form-control" placeholder="Name">
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label>Email Address</label>
<input type="text" name="email" value="{{ $user->email }}" class="form-control" placeholder="Email Address">
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label>Role</label>
<select name="role" class="form-control">
@foreach($roles as $role)
@if($role->id == $user->role)
<option value="{{ $role->id }}" selected>{{ $role->name }}</option>
@else
<option value="{{ $role->id }}">{{ $role->name }}</option>
@endif
@endforeach
</select>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label>Password</label>
<input type="password" name="password" class="form-control" placeholder="New Password">
</div>
</div>
<div class="col-sm-12">
<div class="form-group">
<input type="submit" class="btn btn-info btn-block" value="Update">
</div>
</div>
</form>
@stop
浏览器上的HTML响应为空。我还尝试了<?php dd($errors); ?>
,它显示了以下
Edit User
ViewErrorBag {#168 ▼
#bags: []
}
更多信息请点击此处
@VipindasKS的假设是正确的。由于Laravel版本5.2.28,web中间件通过RouteServiceProviders的方法包含在所有路由中:
protected function mapWebRoutes(Router $router)
{
$router->group([
'namespace' => $this->namespace, 'middleware' => 'web',
], function ($router) {
require app_path('Http/routes.php');
});
}
由于该版本Laravel的默认routes.php文件只包含:
Route::get('/', function () {
return view('welcome');
});
因此,如果你从以前的版本升级,它有一个routes.php文件,如下所示:
Route::group(['middleware' => ['web']], function () {
// web routes
});
你的应用程序会很好地工作,因为有了composer更新,你就不会接触你的RouteServiceProvider(它不会添加mapWebRoutes()方法)。因此,"web"中间件仅添加到"web"组内的路由中。
然而,如果你正在重新安装Laravel(目前为5.2.29),并且有一个带有的routes.php
Route::group(['middleware' => ['web']], function () {
// web routes
});
web中间件堆栈将两次添加到路由中。您可以通过以下方式进行检查:
php artisan route:list
这将表明"web"中间件被添加了两次:
| POST | users/{id}/edit | | App'Http'Controllers'UserController@update | web,web |
这会中断会话的闪存变量,因为它们通常只会在一个会话生命周期内持续。
因此,解决方案是:
如果您拉拉威尔的一个新例子。
您可能需要使用withErrors重定向,以防验证失败
if ($validator->fails()) {
return redirect()
->route('route.here')
->withErrors($validator)
->withInput();
}
此外,请检查
'Illuminate'View'Middleware'ShareErrorsFromSession::class,
app/Http/Kernel.php 中的"web"中间件中有吗
所以你的kernel.php应该看起来像:
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
'App'Http'Middleware'EncryptCookies::class,
'Illuminate'Cookie'Middleware'AddQueuedCookiesToResponse::class,
'Illuminate'Session'Middleware'StartSession::class,
'Illuminate'View'Middleware'ShareErrorsFromSession::class,
'App'Http'Middleware'VerifyCsrfToken::class,
],
'api' => [
'throttle:60,1',
],
];
如果这也不起作用,你可以移动
'Illuminate'View'Middleware'ShareErrorsFromSession::class,
到全球中间件。(只是尝试一下。我不会建议)
**确保会话有效。要返回错误或向浏览器显示消息,您需要运行会话。
从5.2开始,只有当您指定路由应该使用"web"中间件(您已经在routes.php中完成了这一操作)时,会话才会启动
而且,从5.2.28开始,web中间件自动包含在所有路由中,您可以在RouteServiceProvider中看到这一点。因此,我们不想在routes.php或控制器中指定"web"中间件,除非我们有自定义中间件。但是,不确定这是造成问题的原因。