刀片无法访问请求错误(Laravel 5.2)

时间:2016-04-11 20:48:27

标签: php laravel-5.2

自从我使用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: []
}

更多信息here

2 个答案:

答案 0 :(得分:3)

@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
});

您的应用程序将正常工作,因为使用作曲家更新您将不会触及您的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    |

这会破坏Session的flash变量,因为它们通常只打算在一个会话生命周期中持续。

所以解决方案是:

  

如果您使用routes.php文件,请不要使用'web'中间件组   拉了一个新的laravel。

答案 1 :(得分:1)

如果验证失败,您可能需要使用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,

到全球中间件。 (只是为了尝试。我不会建议)

**确保会话有效。 要返回错误或向浏览器发送Flash消息,您需要运行会话。

从5.2开始,如果您指定路由应使用“web”中间件(您已在routes.php中完成),则会话才会启动。

而且,从5.2.28开始,Web中间件自动包含在所有路由中,您可以在RouteServiceProvider中看到这一点。因此,除非我们有自定义中间件,否则我们不希望为routes.php或控制器指定“web”中间件。但是,不确定这会导致问题。