Laravel 5.1学习之 验证

介绍

Laravel 提供了多个不同的渠道来验证你的应用接收的数据。默认情况下,Laravel基础控制器类使用一个ValidatesRequests trait,这个trait提供了验证HTTP请求数据非常多的非常有用的验证规则。


验证入门

为了学习Laravel的强大的验证特性,让我们来看一个简单的例子,这个例子验证了一个表单并且打印了错误信息给用户。

定义规则

首先,假设我们已经在app/Http/routes.php文件中定义了如下的路由:

// Display a form to create a blog post...
Route::get('post/create', 'PostController@create');

// Store a new blog post...
Route::post('post', 'PostController@store');
当然,GET路由将显示一个创建新博客的表单,POST路由将会将新的博客上传到数据库中。

创建新的控制权

接下来,让我们来看一下啊一个简单的处理这些路由的控制器。我们先不实现store方法:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class PostController extends Controller
{
    /**
     * Show the form the create a new blog post.
     *
     * @return Response
     */
    public function create()
    {
        return view('post.create');
    }

    /**
     * Store a new blog post.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        // Validate and store the blog post...
    }
}

编写验证逻辑


现在我们可以来实现store方法了,并且在此方法中验证新的博客post。如果你查看过App\Http\Controllers\Controller类,你将看到类使用了ValidatesRequests trait。这个trait为你所有的控制器提供了非常实用的validate方法。

validate方法接收一个传入的HTTP 请求和一系列的验证规则。如果验证规则通过了,你的代码将会继续执行。一旦失败,将会抛出一个异常,并且对应的错误响应会自动的传回给用户。对于传统的HTTP请求来讲,一个重定向响应将会被生成,同时JSON响应将会被传递给AJAX请求。

为了更好的理解validate方法,让我们重新回来store方法:

/**
 * Store a new blog post.
 *
 * @param  Request  $request
 * @return Response
 */
public function store(Request $request)
{
    $this->validate($request, [
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ]);

    // The blog post is valid, store in database...
}
正如你所看到的,我们传递给validate方法一个HTTP请求和我们想要的验证规则。同样,如果验证失败,相应的相应将会自动生成,如果验证通过,我们的控制器将会继续正常执行。

嵌套属性

如果你的HTTP请求包含嵌套参数,你可以使用点语法来特殊声明他们:

$this->validate($request, [
    'title' => 'required|unique:posts|max:255',
    'author.name' => 'required',
    'author.description' => 'required',
]);

显示验证错误

那么,如果传递进来的请求参数没有通过验证怎么办?前面提及过,Laravel将会自动的将用户重定向会他们先前的路径。此外,所有的验证错误将会自动的刷新岛session中。

注意,我们并不需要在GET路由上为视图绑定错误信息。因为Laravel总是会自动的检查session数据上面的错误信息,并且当他们可用的时候自动的见过他们绑定到视图上。所以,在所有视图中的每个请求$error变量都是可用的,你可以假定$error变量一直存在并且可以安全的使用。$error是Illuminate\Support\MessageBag 的一个实例。更多关于这个对象的信息,可以参考相关文档。

因此,在我们的例子中,用户在验证失败后将会被重定向到控制器的create方法,我们可以来输出这段错误信息:

<!-- /resources/views/post/create.blade.php -->

<h1>Create Post</h1>

@if (count($errors) > 0)
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

<!-- Create Post Form -->

自定义错误格式

如果你希望在验证失败的时候能够自定义刷新岛session中的错误信息格式,你可以在基础控制器基类中重写 formatValidationErrors方法。不要忘记引入 Illuminate\ Contracts\Validation\Validator 类:

<?php

namespace App\Http\Controllers;

use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;

abstract class Controller extends BaseController
{
    use DispatchesJobs, ValidatesRequests;

    /**
     * {@inheritdoc}
     */
    protected function formatValidationErrors(Validator $validator)
    {
        return $validator->errors()->all();
    }
}

AJAX请求和验证

上例中,我们使用一个传统的表单来发送数据给应用。然而,许多应用使用AJAX请求。当在AJAX请求中使用validate方法时,Laravel将不会生成一个重定向请求。取而代之,Laravel将生成一个JSON请求,该请求包含所有的验证错误。这个JSON响应将会附带一个422HTTP状态码。

其他验证方法

手动创建验证

如果你不想要使用ValidatesRequests的trait中包含的validate方法,你可以使用Validator外观件手动创建一个validator实例。外观件的make方法生成了一个新的validator实例:

<?php

namespace App\Http\Controllers;

use Validator;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class PostController extends Controller
{
    /**
     * Store a new blog post.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'title' => 'required|unique:posts|max:255',
            'body' => 'required',
        ]);

        if ($validator->fails()) {
            return redirect('post/create')
                        ->withErrors($validator)
                        ->withInput();
        }

        // Store the blog post...
    }
}
传递给make方法的第一个参数是待验证的数据,第二个参数为需要验证数据的验证规则。

在检查完请求是否通过验证后,你可以使用withErrors方法来刷新session中的错误信息。当使用这个方法,$error变量将会自动的将变量在你的视图中共享,允许你很方便的给用于显示错误。withErrors方法接收一个validator或者MessageBag或者PHP数组。


命名错误集合包

如果你在单个页面上有多个表单,那么$error变量到底显示的是哪个表单的验证错误呢?这时我们可以针对MessageBag进行命名,允许你从特殊的表单中取出错误信息。只需要简单的传递一个名字作为withErrors方法的第二个参数:
return redirect('register')
            ->withErrors($validator, 'login');
而后你可以通过以下方式来访问命名后的MessageBag实例:

{{ $errors->login->first('email') }}

Validation的after钩子

validator同样允许你在验证完成后附加一个回调。这样你可以方便的执行更多的验证,甚至给错误信息集合中添加更多的错误信息。使用方式如下:
$validator = Validator::make(...);

$validator->after(function($validator) {
    if ($this->somethingElseIsInvalid()) {
        $validator->errors()->add('field', 'Something is wrong with this field!');
    }
});

if ($validator->fails()) {
    //
}

表单请求验证

对于更加复杂的验证脚本,你也可以创建一个“表单请求”。
表单请求是包含有验证逻辑的自定义请求类。我们可以使用CLI命令 make:request来创建它:
php artisan make:request StoreBlogPostRequest
生成的类将会被防止在app/Http/Requests目录下,让我们在rules中增加一些validation规则:
/**
 * Get the validation rules that apply to the request.
 *
 * @return array
 */
public function rules()
{
    return [
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ];
}
写好后这些规则如何被应用呢??你只需要将在控制器方法中显示其类型就可以了,进来的请求表单会在控制器方法被调用前执行,保证了控制器代码的整洁:

/**
 * Store the incoming blog post.
 *
 * @param  StoreBlogPostRequest  $request
 * @return Response
 */
public function store(StoreBlogPostRequest $request)
{
    // The incoming request is valid...
}
如果严重失败,会生成一个重定向的响应将用于重定向到上一页面。错误信息将会被刷新到session中,可以通过$error变量来显示他们。如果请求是一个AJAX请求,将会返回状态码为422的HTTP响应,包含一个JSON的严重错误信息。


授权表单请求

表单请求同样包含一个authorize方法,使用这个方法,你可以检查已认证用户是否拥有更新给定资源的授权。例如,如果一个用户尝试更新一个博客评论,那么如何判断该用户是否拥有这条评论呢?来看下面的例子:

/**
 * Determine if the user is authorized to make this request.
 *
 * @return bool
 */
public function authorize()
{
    $commentId = $this->route('comment');

    return Comment::where('id', $commentId)
                  ->where('user_id', Auth::id())->exists();
}
注意上例中的route方法,这个方法授权你获取定义在路由中的URI参数,例如例子下面的{comment}参数。

Route::post('comment/{comment}');

如果authorize方法返回false,将会返回一个带有403状态码的HTTP响应,控制器后续的方法将不会被执行。


如果你计划在应用的其他地方任职逻辑,那么直接在authorize方法中返回true就行了。

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

自定义刷新到session中的ERROR格式

如果你希望自定义刷新到session中的验证错误的格式,重新你的请求基类(App\Http\Requests\Request)中的formatErrors方法,不要忘记在文件的顶端引入 Illuminate\ Contracts\Validation\Validator 类:
/**
 * {@inheritdoc}
 */
protected function formatErrors(Validator $validator)
{
    return $validator->errors()->all();
}

自定义错误信息

你可以通过重写messages方法来自定义错误信息。这个方法应该返回属性/规则对来对应错误信息:
/**
 * Get the error messages for the defined validation rules.
 *
 * @return array
 */
public function messages()
{
    return [
        'title.required' => 'A title is required',
        'body.required'  => 'A message is required',
    ];
}

错误信息的一些常用获取方法

validator实例调用了errors方法后,你将取得一个 Illuminate\ Support\MessageBag 实例,该实例可以提供一系列的便捷的方法来取得error信息。

取出一个字段中的第一条错误信息

使用first方法来去除给给定字段的第一条错误信息:

$messages = $validator->errors();

echo $messages->first('email');

取出一个字段的所有的错误信息:

如果你希望简单的取出一个字段所有的数组错误信息,使用get方法:
foreach ($messages->get('email') as $message) {
    //
}

取出所有字段的所有错误信息:

foreach ($messages->all() as $message) {
    //
}

判断某一字段的错误信息是否存在:

if ($messages->has('email')) {
    //
}

取出带有格式的一条错误信息:

echo $messages->first('email', '<p>:message</p>');

取出带有格式的所有错误信息:

foreach ($messages->all('<li>:message</li>') as $message) {
    //
}

自定义错误信息

如果需要,可以让验证使用自定义错误信息。有几种方式来自定义信息。第一种,你可以传递一个自定义信息作为Validator::make方法的第三个参数:

$messages = [
    'required' => 'The :attribute field is required.',
];

$validator = Validator::make($input, $rules, $messages);
在这个例子中,:attribute前置参数在验证中将会由真正的字段替代,你可以在验证消息中使用其他的前置参数,例如:

$messages = [
    'same'    => 'The :attribute and :other must match.',
    'size'    => 'The :attribute must be exactly :size.',
    'between' => 'The :attribute must be between :min - :max.',
    'in'      => 'The :attribute must be one of the following types: :values',
];

为一个给定的请求特殊化一个自定义信息

有时你希望只针对一个特殊的字段来自定义错误信息,你可以使用点语法,如下:
$messages = [
    'email.required' => 'We need to know your e-mail address!',
];

在语言文件中特殊自定义信息


如果不想直接在代码中自定义错误消息的话,你可以在 resources / lang / xx / validation . php 语言温江中添加你的信息给custom数组:

'custom' => [
    'email' => [
        'required' => 'We need to know your e-mail address!',
    ],
],


可用的验证规则

略过。

有条件的添加规则(字段不知道是否存在)

在一些情况下,你希望只有当字段出现在请求中的时候再运行验证检查。快速完成这个,可以添加sometimes规则到你的规则列表:
$v = Validator::make($data, [
    'email' => 'sometimes|required|email',
]);
例子中,email字段只有在它出现在$data数组中的时候才会验证。

复杂的有条件验证

有时你可能希望添加一个更加复杂的有条件验证,比如你希望在另一个字段大于100的时候才需要一个字段。或者只有当另一个字段存在的时候,另外两个字段才进行验证?很简单,我们先新建一个Validator实例:

$v = Validator::make($data, [
    'email' => 'required|email',
    'games' => 'required|numeric',
]);
让我们假设网站应用服务于玩具回收者,如果一个玩具回收折拥有超过100个玩具并且注册我们的网站,我们希望他们解释为啥他们有这么多玩具,例如,大概他们运行一个玩具二次销售商店,或者他们就是喜欢回收。为了有条件的添加这个需求,我们可以在Validator实例上使用sometimes方法。
$v->sometimes('reason', 'required|max:500', function($input) {
    return $input->games >= 100;
});
传递给sometimes方法的第一个参数是我们希望选择性验证的字段。第二个参数使我们希望添加的规则。如果闭包(第三个参数)返回true,那么规则将会被添加,这使得复杂的验证变得非常简单,你甚至可以一次性为几个字段添加选择性的验证:


$v
- > sometimes( [ 'reason' , 'cost' ] , 'required' , function ( $input ) { return $input - > games >= 100 ; } ) ;

自定义验证规则


略过。

英文原文地址:http://www.golaravel.com/laravel/docs/5.1/validation/#form-request-validation

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值