流明自定义验证

Posted

技术标签:

【中文标题】流明自定义验证【英文标题】:Lumen Custom Validation 【发布时间】:2018-09-08 13:36:43 【问题描述】:

我正在尝试在 lumen 中实现自定义验证规则,并且我正在关注 lumen 5.6 的文档。它说要参考 laravel 验证以了解如何使用验证。我目前正在尝试进行验证以检查该值是否为真空值。所以 $x === "" 意味着它失败了这是我创建的位于 App\Rules 文件夹中的规则。

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class TrueNull implements Rule

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    
        if($value === "") 
            return false;
         else 
            return true;
        
    

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    
        return 'The :attribute cannot be an empty string.';
    

我直接从 lumen 文档中复制了这个,并对 pass 函数进行了修改。在我的模态中有

use Illuminate\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Database\Eloquent\Model;
use Laravel\Lumen\Auth\Authorizable;
use App\Rules\TrueNull;
use Validator;

然后

public function validate($data)

    // make a new validator object
    $v = Validator::make($data, 
    [
        'x' => ['regex:/^(?=.+)(?:[1-9]\d*|0)?(?:\.\d+)?$/', new TrueNull]
    ]

但是 TrueNull 的验证永远不会发生,我错过了一个连接还是真的令人沮丧,因为文档说这应该可以工作。 这是我的控制器调用我正在验证的更新。

public function update(Request $request, $id)
    
        /*
            In middleware need to add community id to request.
        */
        try 
            $site = Site::findOrFail($id);

            if ($site->validate($request->all())) 
                $site->fill($request->all());

                // save
                $site->save();
             else 
                return response()->json($site->errors(), 422);
            
         catch (Exception $e) 
            return response()->json($e, 422);
        

        return response()->json($site, 200);
    

【问题讨论】:

也许添加 Laravel 中可用的 ConvertEmptyStringsToNull 中间件 (see here) 是一种解决方案?这不仅可以让您删除额外的验证,而且从可用性的角度来看也可以派上用场。 我不想在我的 api 中执行任何数据操作。我想拒绝发送“”而不是空的任何非字符串字段。我想强制我们的前端发送正确的数据,而不是仅仅假设因为“”在我的工作中意味着不同的东西。 好的,然后回到你的问题。我不完全确定 lumen 中的验证器如何处理多个验证规则(即首次错误失败或全部评估),但在我看来,您的正则表达式已经排除了空字符串。所以也许如果你颠倒数组中验证规则的顺序,你可以让它因为另一个规则的空字符串而失败? 我也有同样的想法,我删除了正则表达式,只是保留了验证规则,但它仍然没有评估“”。如果请求有键但属性是“”,它似乎在流明中很奇怪,它只是跳过所有内容。 【参考方案1】:

为了将来参考,我发现了一个随机的 sn-p 代码,它抵消了 Lumen 的基本文档。在我的 TrueNull 类而不是实现规则中,我将其更改为实现 ImplicitRule 并将使用更改为 \ImplicitRule,现在它发现“”不是空值。

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\ImplicitRule;

class TrueNull implements ImplicitRule

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    
        if($value === "") 
            return false;
         else 
            return true;
        
    

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    
        return 'The :attribute cannot be an empty string.';
    

【讨论】:

这很有趣,感谢您发布解决方案!不过,我对您的实现有一个评论:名称 TrueNull 对我来说意味着只有 null 通过了测试,而空字符串和填充字符串都没有。但是,在当前的实现中,只有空字符串不会通过。所以你可能想把它改成:return $value === null; 这是个好主意,感谢您的更新!我会将其添加到我的验证中。 我如何在 Lumen 5.3 中使用它,其中合同不同且文档没有有用的帮助! 用法示例:``` $this->validate($request, [ "value" => ["required", new TrueNull()], ]); ```【参考方案2】:

@Alexander Beyers 的答案很棒,但它不适用于 Lumen 5.3。以下是如何为 Lumen 5.3 创建有组织的自定义规则。

在 app dir 下创建目录名称规则并创建以下文件:

namespace App\Rules;
use Illuminate\Support\Facades\Validator;

class AlphaSpace

    public static function validate()
        //Extending the custom validation rule.
        Validator::extend('alpha_spaces', function ($attribute, $value) 
            // This will only accept alpha and spaces.
            // If you want to accept hyphens use: /^[\pL\s-]+$/u.
            return preg_match('/^[\pL\s]+$/u', $value);
        );
    

打开文件resources/lang/en/validation 并在自定义验证下添加以下内容: 注意:(自定义验证下仅用于维护)

/*
|--------------------------------------------------------------------------
| Custom Validation Language Lines
|--------------------------------------------------------------------------
|
| Here you may specify custom validation messages for attributes using the
| convention "attribute.rule" to name the lines. This makes it quick to
| specify a specific custom language line for a given attribute rule.
|
*/
'alpha_spaces' => 'The :attribute may only contain letters and spaces.',

调用app/Providers/AppServiceProvider::boot()中的规则:

use HRM\Core\Rules\AlphaSpace;

class AppServiceProvider extends ServiceProvider

    public function boot() 
        AlphaSpace::validate();
    

// class will carry on with the stuffs!

现在你可以在任何你想要的地方使用它:

'first_name' => 'required|alpha_spaces|min:3|max:50',
'last_name' => 'required|alpha_spaces|min:3|max:50',

【讨论】:

谢谢,使用 Lumen 6x。只需取消注释$app-&gt;register(App\Providers\AppServiceProvider::class); 如果您使用的是 lumen 6x,请务必将资源/lang/en/validation 文件从 laravel 6 版本复制到您的 lumen 应用程序中,然后在名为 custom 的键下添加您的自定义验证: 'custom' => [ 'attribute-name' => [ 'rule-name' => 'custom-message', ], ],这就是它知道您的自定义验证规则的方式。没有这个,您的错误消息将不再是人类可读的形式,而是您为必填字段获得的内容将是“validation.required”而不是“:attribute is required”,其中 :attribute 将是请求参数的名称【参考方案3】:

Version: Lumen 7.X

首先,在app/Providers/AppServiceProvider.php 中声明您的规则。 使用您的规则方法创建一个boot(),如下所示(我为电话号码注册了一个规则)。

public function register()
    
        //
    

    public function boot()
    
        app('validator')->extend('phone', function ($attribute, $value) 
            return preg_match('%^(?:(?:\(?(?:00|\+)([1-4]\d\d|[1-9]\d?)\)?)?[\-\.\ \\\/]?)?((?:\(?\d1,\)?[\-\.\ \\\/]?)0,)(?:[\-\.\ \\\/]?(?:#|ext\.?|extension|x)[\-\.\ \\\/]?(\d+))?$%i', $value) && strlen($value) >= 10;
        );

        app('validator')->replacer('phone', function ($message, $attribute, $rule, $parameters) 
            return 'Phone number has wrong format.';
        );
    

与 Laravel 相对的不同部分,最重要的是,AppServiceProvider 默认没有在 Lumen 中注册。

您需要转到bootstrap/app.php 并取消注释以下行:

 $app->register(App\Providers\AppServiceProvider::class);

也许你想做composer dumpautoload,以防万一,但没有它应该也能工作。

然后,在您的代码中:

$validator = Validator::make(
   $request->all(),
   [ 
       'tel' => 'required|phone' 
   ],
   [ 
       'tel.required' => 'Phone is required', 
       'tel.phone' => 'Phone has wrong format'
   ]
);

应该是这样的!

【讨论】:

以上是关于流明自定义验证的主要内容,如果未能解决你的问题,请参考以下文章

流明封装。如何加载自定义validation.php 消息文件?

未定义身份验证保护驱动程序 [api]。流明、野狗、JWTAuth

Lumen 提供验证错误的代码

在没有立面的流明中验证路由参数

WCF 自定义验证器:如何从自定义验证器初始化“用户”对象

SonarQube添加自定义规则:实践验证