简体   繁体   English

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

[英]Request Errors not accessible in blade (Laravel 5.2)

It had been many months since I'm using laravel but never faced such problem. 我使用laravel已经好几个月但从未遇到过这样的问题。

I have made a simple Request class to validate the the update user request which works fine if validation rules are followed. 我已经创建了一个简单的Request类来验证更新用户请求,如果遵循验证规则,该请求可以正常工作。 If validation rule fails we should come back to the previous page and display all errors in html. 如果验证规则失败,我们应该回到上一页并显示html中的所有错误。

According to me I have written everything correctly as I used to write in other applications but the $errors seems to be inaccessible in blade 根据我的说法,我已经正确编写了所有内容,因为我曾经在其他应用程序中编写,但$errors blade中的$errors似乎无法访问

Following are my required code snippets to debug: 以下是我需要调试的代码片段:

routes.php routes.php文件

Route::group(['middleware' => ['web']], function () {
    Route::get('/users/{id}/edit', 'UserController@edit');
    Route::post('/users/{id}/edit', 'UserController@update');
});

UserController.php 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 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 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

The HTML response on browser is blank. 浏览器上的HTML响应是空白的。 I also tried <?php dd($errors); ?> 我也试过<?php dd($errors); ?> <?php dd($errors); ?> which displayed the following <?php dd($errors); ?>显示以下内容

Edit User

ViewErrorBag {#168 ▼
  #bags: []
}

More info here 更多信息在这里

@VipindasKS is right with his assumption. @VipindasKS是他的假设。 Since Laravel Version 5.2.28 the web middleware is included in all routes via the RouteServiceProviders's method: 从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');
    });
}

Since that version Laravel's default routes.php file only contains: 从那个版本开始,Laravel的默认routes.php文件只包含:

Route::get('/', function () {
    return view('welcome');
});

So if you upgrade from a previous version, that has a routes.php file like this: 因此,如果您从以前的版本升级,那么有一个routes.php文件,如下所示:

Route::group(['middleware' => ['web']], function () {
   // web routes
});

Your application will just work fine, because with an composer update you won't touch your RouteServiceProvider (It does not add the mapWebRoutes() method). 您的应用程序将正常工作,因为使用作曲家更新您将不会触及您的RouteServiceProvider(它不会添加mapWebRoutes()方法)。 So the 'web' middleware is only added to the routes within the 'web' group'. 所以'web'中间件只被添加到'web'组中的路由'。

However if you are pulling a fresh installation of Laravel ( currently 5.2.29 ) and have a routes.php with 但是,如果你要拉一个Laravel的新安装(目前为5.​​2.29)并且有一个routes.php

Route::group(['middleware' => ['web']], function () {
   // web routes
});

The web middleware stack will be added twice to the routes. Web中间件堆栈将添加两次到路由。 You can check this via: 您可以通过以下方式查看:

php artisan route:list

Which will show that the 'web' middleware is added twice: 这将显示“web”中间件被添加两次:

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

This breaks the Session's flash variables as they are normally only intended to last only during one session lifecycle. 这会破坏Session的flash变量,因为它们通常仅用于在一个会话生命周期中持续。

So the solution is: 所以解决方案是:

Don't use the 'web' middleware group in the routes.php file if you pulled a fresh instance of laravel. 如果拉出一个新的laravel实例,请不要在routes.php文件中使用“web”中间件组。

You may want to use withErrors redirect, in case validation fails 如果验证失败,您可能希望使用withErrors重定向

    if ($validator->fails()) {
        return redirect()
            ->route('route.here')
            ->withErrors($validator)
            ->withInput();
    }

Also, please check 另外,请检查

  \Illuminate\View\Middleware\ShareErrorsFromSession::class,

is there in 'web' middleware in app/Http/Kernel.php 在app / Http / Kernel.php中有'web'中间件

so your kernel.php should look something like: 所以你的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',
    ],
];

If that too doesn't work, you can move the 如果这也不起作用,你可以移动

  \Illuminate\View\Middleware\ShareErrorsFromSession::class,

to the global middleware. 全球中间件。 (just to try. I won't suggest) (只是为了尝试。我不会建议)

** Make sure sessions work. **确保会话有效。 To have errors returned or to flash messages to the browser, you need to have a session running. 要返回错误或将Flash消息发送到浏览器,您需要运行会话。

From 5.2, sessions only start if you specify that the route should use the 'web' middleware (which is already done by you in the routes.php). 从5.2开始,如果您指定路由应使用“web”中间件(您已在routes.php中完成),则会话才会启动。

And, From 5.2.28, web middleware is automatically included in all routes, you can see this in the RouteServiceProvider . 并且,从5.2.28开始,Web中间件自动包含在所有路由中,您可以在RouteServiceProvider中看到这一点 so, we don't want to specify a 'web' middleware to the routes.php or in controller unless we have a custom middleware. 因此,除非我们有自定义中间件,否则我们不希望为routes.php或控制器指定“web”中间件。 But, not sure this caused the problem. 但是,不确定这会导致问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM