【问题标题】:Request Errors not accessible in blade (Laravel 5.2)刀片中无法访问的请求错误(Laravel 5.2)
【发布时间】:2016-08-02 05:18:34
【问题描述】:

自从我使用 laravel 以来已经好几个月了,但从未遇到过这样的问题。

我制作了一个简单的请求类来验证更新用户请求,如果遵循验证规则,它可以正常工作。如果验证规则失败,我们应该返回上一页并在 html 中显示所有错误。

据我说,我已经正确地编写了所有内容,就像我过去在其他应用程序中编写的一样,但是 $errors 在刀片中似乎无法访问

以下是我需要调试的代码 sn-ps:

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 响应为空白。 我还尝试了&lt;?php dd($errors); ?&gt;,它显示了以下内容

Edit User

ViewErrorBag {#168 ▼
  #bags: []
}

更多信息here

【问题讨论】:

  • 能否请您附上更新表格?我想它位于 edit.blade.php ?
  • 添加表单代码@shock_gone_wild
  • 这太疯狂了......我已经像你一样设置了东西,它对我来说很好(相同的 laravel 版本)
  • 您在错误日志中看到任何异常吗?看起来请求没有正确重定向。
  • storage/logs/laravel.log没有错误

标签: php laravel-5.2


【解决方案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,

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

** 确保会话正常工作。 要返回错误或向浏览器闪烁消息,您需要运行会话。

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

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

【讨论】:

  • 正如建议的那样,它在移动 \Illuminate\Session\Middleware\StartSession::class\Illuminate\View\Middleware\ShareErrorsFromSession::class 时起作用,一切都开始工作了,但我需要知道为什么会这样。 routes.php 一定有问题
  • @Cyber​​supernova 正如我在回答中提到的那样,错误消息仅在有会话时才有效。全局中间件是每个请求都通过的东西。正如您在 routes.php 中提到的“web”作为中间件组,web 中间件应该包含与会话相关的行。请详细了解群组路由here
  • 是的,这绝对正确,但我 $middlewareGroups 数组与您在回答中提到的完全一样。我们也不能认为路由没有通过该组,就好像我没有在表单中给出csrf_token 然后\App\Http\Middleware\VerifyCsrfToken::class 中间件抛出它的异常TokenMismatchException in VerifyCsrfToken.php line 67。那么为什么会话中间件不起作用呢?
  • 我还想提一下 return view('some.view)-&gt;withErrors('My Custom Error') 工作正常,$errors 可以在刀片中访问,正如我在此处提到的 github.com/laravel/framework/issues/13145
  • @Cyber​​supernova 能否请您在评论使用 App\Http\Requests 后发布输出;在你的 UserController.php
【解决方案2】:

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

网络中间件堆栈将两次添加到路由中。您可以通过以下方式检查:

php artisan route:list

这将表明“网络”中间件被添加了两次:

| POST      | users/{id}/edit          |                  | App\Http\Controllers\UserController@update      | web,web    |

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

所以解决办法是:

如果你不使用 routes.php 文件中的 'web' 中间件组 拉了一个新的 laravel 实例。

【讨论】:

  • 感谢这工作。当我拉5.2.29 时,我以为我必须手动添加web 中间件,我自己创建了问题
猜你喜欢
  • 1970-01-01
  • 2016-10-06
  • 2016-12-29
  • 2017-11-03
  • 2017-02-24
  • 2016-09-12
  • 2016-08-15
  • 2017-03-01
  • 1970-01-01
相关资源
最近更新 更多