最适合入门的Laravel中级教程(三)表单验证

做开发有个原则是永远不能信任用户输入的数据;
即便前端已经做了验证;
在后端 php 也必须要再次验证;
laravel 为表单验证提供了强大且简单的方案;
创建示例路由:
routes/web.php

Route::prefix('validation')->group(function () {
    Route::get('create', 'ValidationController@create');
    Route::post('store', 'ValidationController@store');
    Route::get('edit', 'ValidationController@edit');
    Route::post('update', 'ValidationController@update');
});

创建控制器

php artisan make:controller ValidationController --resource

app/Http/Controllers/ValidationController.php

public function create()
{
    return view('validation.create');
}

创建视图;
这里直接把官方自带的注册页面复制过来做示例了;
为了方便验证后台我把 html 标签的验证删除了;
并增加了一个 tag 选项;
resources/views/validation/create.blade.php

@extends('layouts.app')

@section('content')
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <div class="panel panel-default">
                    <div class="panel-heading">注册</div>

                    <div class="panel-body">
                        <form class="form-horizontal" method="POST" action="{{ url('validation/store') }}">
                            {{ csrf_field() }}

                            <div class="form-group{{ $errors->has('tag') ? ' has-error' : '' }}">
                                <label class="col-md-4 control-label">标签</label>

                                <div class="col-md-6">
                                    <select class="form-control" name="tag">
                                        <option value="">请选择标签</option>
                                        <option value="1">1</option>
                                        <option value="2">2</option>
                                    </select>

                                    @if ($errors->has('tag'))
                                        <span class="help-block">
                                        <strong>{{ $errors->first('tag') }}</strong>
                                    </span>
                                    @endif
                                </div>
                            </div>

                            <div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
                                <label for="name" class="col-md-4 control-label">用户名</label>

                                <div class="col-md-6">
                                    <input id="name" type="text" class="form-control" name="name" value="{{ old('name') }}" autofocus>

                                    @if ($errors->has('name'))
                                        <span class="help-block">
                                        <strong>{{ $errors->first('name') }}</strong>
                                    </span>
                                    @endif
                                </div>
                            </div>

                            <div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
                                <label for="email" class="col-md-4 control-label">邮箱</label>

                                <div class="col-md-6">
                                    <input id="text" type="email" class="form-control" name="email" value="{{ old('email') }}">

                                    @if ($errors->has('email'))
                                        <span class="help-block">
                                        <strong>{{ $errors->first('email') }}</strong>
                                    </span>
                                    @endif
                                </div>
                            </div>

                            <div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
                                <label for="password" class="col-md-4 control-label">密码</label>

                                <div class="col-md-6">
                                    <input id="password" type="text" class="form-control" name="password">

                                    @if ($errors->has('password'))
                                        <span class="help-block">
                                        <strong>{{ $errors->first('password') }}</strong>
                                    </span>
                                    @endif
                                </div>
                            </div>

                            <div class="form-group">
                                <label for="password-confirm" class="col-md-4 control-label">确认密码</label>

                                <div class="col-md-6">
                                    <input id="password-confirm" type="text" class="form-control" name="password_confirmation">
                                </div>
                            </div>

                            <div class="form-group">
                                <div class="col-md-6 col-md-offset-4">
                                    <button type="submit" class="btn btn-primary">
                                        注册
                                    </button>
                                </div>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>
@endsection

现在到了后台验证的时候了;
laravel 可以直接在控制器中直接写验证逻辑;
不过我建议单独创建验证类;
以控制器名为目录;
以方法名为文件名;
这里为 store 方法创建一个验证类;

php artisan make:request Validation/Store

执行命令会生成 app/Http/Requests/Validation/Store.php 文件;

<?php

namespace App\Http\Requests\Validation;

use Illuminate\Foundation\Http\FormRequest;

class Store extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return false;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            //
        ];
    }
}

默认生成的验证类中只有 authorizerules 方法;
authorize() 主要用于验证权限;
如上面代码所示默认直接返回 fase 意味着所有的请求都不能通过验证;
假如说只允许 user_id 为 1 的用户执行 store 方法;
我们可以这样改写 验证类的 authorize()

    public function authorize()
    {
        return Auth::id() === 1 ? true : false;
    }

还有很多时候我们并不需要验证身份;
那直接返回 true 即可;

    public function authorize()
    {
        return true;
    }

另外就是 rules 方法;
根据前端页面增加以下验证;

public function rules()
{
    return [
        'tag' => 'required',
        'name' => 'required|string|max:255',
        'email' => 'required|string|email|max:255|unique:users',
        'password' => 'required|string|min:6|confirmed',
    ];
}

这些规则都可以在文档中找到表单验证
要使用这个验证器也很简单;
只需要在 store 方法的类型约束中使用 Store 即可;

use App\Http\Requests\Validation\Store;

public function store(Store $request)
{
    dump($request->all());
}

增加验证后我们访问 /validation/create 页面点击注册按钮;

当点击注册按钮的时候会刷新下页面并显示红色的提示信息;
但是提示信息全是英文;
要想显示中文我们可以翻译 resources/lang/en/validation.php 文件中的内容;
另外 overtrue 有一个翻译好的扩展包可以供我们使用 laravel-lang

composer require "overtrue/laravel-lang:~3.0"

在 config/app.php 文件中把 Illuminate\Translation\TranslationServiceProvider::class, 替换成 Overtrue\LaravelLang\TranslationServiceProvider::class,;
再次点击注册按钮就可以看到中文的提示信息了;

但是我们可以看到 tag 并没有被翻译出来;
像这类非通用性的字段;
我们可以在验证类 app/Http/Requests/Validation/Store.php 中定义 attributes 方法;
在方法中以键值对的方式翻译字段;

public function attributes()
{
    return [
        'tag' => '标签',
    ];
}

再次刷新页面;

标签是翻译过来了;
但是我明明一个下拉选择标签但是提示却是输入类型的不能为空;
叔可以忍婶婶是忍不了了;
像这类情况我们还可以在验证类 app/Http/Requests/Validation/Store.php 中定义一个 messages 方法;
在方法中以字段拼接验证类型来翻译字段和验证类型的错误信息;

public function messages()
{
    return [
        'tag.required' => '必须选择标签',
    ];
}


泼飞克特;
终于如愿以偿;
验证失败的信息都是在 session 中存储;
可以使用 session() 获取到失败的信息;

另外 laravel 还在 app/Http/Kernel.php 中注册了 ShareErrorsFromSession 中间件;
它的作用是可以让我们在视图文件直接使用储存了错误信息的变量 $errors

白俊遥博客
请先登录后发表评论
  • latest comments
  • 总共11条评论
白俊遥博客

zwsnail :我改了true也和下面那位朋友一样,为什么没有被验证,直接跳过去?请问是laravel版本原因吗?我看我的才2.3.0

2020-01-01 18:03:20 回复

白俊遥博客

zwsnail :还有很多时候我们并不需要验证身份;那直接返回 true 即可应该是false吧?--------------------------------刚刚知道为什么不能用了,因为那个public function store(Store $request)没改成是Store的model

2020-01-01 18:18:47 回复

白俊遥博客

:Store  里面authorize()直接return true

2019-11-19 14:11:18 回复

白俊遥博客

只是→路过、、、 :store方法里,我已经复制录入rule和改了authorize为true  但是一提交,根本不走验证还是直接就打印出来提交的东西了

2019-08-13 15:25:19 回复

白俊遥博客

buptzlk :推荐一个博客项目,后端使用laravel5.8开发,前端vue,前后分离,https://github.com/beijing-xiaotinghua/layBlog-ui 欢迎交流学习

2019-08-03 16:37:01 回复

白俊遥博客

山海 :666白俊遥博客

2019-03-13 21:42:45 回复

白俊遥博客

小牛-承接搭建-站长信誉 :学习啊白俊遥博客

2019-03-10 22:39:23 回复

白俊遥博客

小牛-承接搭建-站长信誉 :学习看看!不错的论坛

2019-03-10 22:40:25 回复

白俊遥博客

小牛-承接搭建-站长信誉 :学习无限极评论写法!!

2019-03-10 22:41:29 回复

白俊遥博客

NULL :enen 

2019-03-13 13:14:00 回复

白俊遥博客

Shin Chan :借鉴学习

2019-03-17 01:38:25 回复