首页 > 解决方案 > Laravel 中的自定义验证器规则总是返回消息

问题描述

我有一个找不到解决方案的问题,实际上是 2 个问题。

第一个问题如下,我制作了一个自定义验证规则来验证“NIF”(葡萄牙使用的身份),直到此时一切正常,验证规则正在工作,问题是返回的消息,消息总是“给定的数据无效”。但应该出现“无效的 NIF”。

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class NifValidator implements Rule
{
    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        $ignoreFirst = true;
        $nif = trim($value);
        \Log::info("Valida Rules NIF: " . $nif);
        //Verificamos se é numérico e tem comprimento 9
        if (!is_numeric($nif) || strlen($nif) != 9) {
            return false;
        } else {
            $nifSplit = str_split($nif);
            //O primeiro digíto tem de ser 1, 2, 5, 6, 8 ou 9
            //Ou não, se optarmos por ignorar esta "regra"
            if (
                in_array($nifSplit[0], [1, 2, 5, 6, 8, 9])
                ||
                $ignoreFirst
            ) {
                //Calculamos o dígito de controlo
                $checkDigit = 0;
                for ($i = 0; $i < 8; $i++) {
                    $checkDigit += $nifSplit[$i] * (10 - $i - 1);
                }
                $checkDigit = 11 - ($checkDigit % 11);
                //Se der 10 então o dígito de controlo tem de ser 0
                if ($checkDigit >= 10) {
                    $checkDigit = 0;
                }

                //Comparamos com o último dígito
                if ($checkDigit == $nifSplit[8]) {
                    \Log::info("VALIDA NIF  TRUE");
                    return true;
                } else {
                    \Log::info("VALIDA NIF  False");
                    return false;
                }
            } else {
                \Log::info("VALIDA NIF  false");
                return false;
            }
        }
    }

    public function validate($attribute, $value, $params)
    {
        return $this->passes($attribute, $value);
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return ':attribute inválido';
    }
}

我的 AppServiceProvider.php

<?php

namespace App\Providers;

use Hyn\Tenancy\Environment;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        $env = app(Environment::class);

        if ($fqdn = optional($env->hostname())->fqdn) {
            config(['database.default' => 'tenant']);
        }

        // money format
        Str::macro('money', function ($price) {
            return number_format($price, 2, ',', '.');
        });

        \Validator::extend('nifvalidator', '\App\Rules\NifValidator@validate');
    }

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

我的控制器

<?php

namespace App\Http\Controllers\Auth;

use App\Authentication\Register;
use App\Http\Controllers\Controller;
use Exception;

class RegisterController extends Controller
{
    use \App\Traits\Helpers\ResponseJSON;

    public function create()
    {
        try {
            $payload = request()->all();

            $rules = [
                'nif' => 'required',
                'name' => 'required',
                'email' => 'required|email',
                'password' => [
                    'required',
                    'string',
                    'min:8', // must be at least 8 characters in length
                    'regex:/[A-Za-z]/', // must contain at least one uppercase letter
                    'regex:/[0-9]/', // must contain at least one digit
                ],
                'country' => 'required',
            ];

            $messages = [
                'password.regex' => 'A password precisa ter no minimo 1 letra e 1 número',
            ];

            //portugal
            if (176 == $payload['country']) {
                // if (!Cliente::validaNif($payload['nif'])) {
                //     throw new Exception("register.nif_invalid");
                // }
                $rules['nif'] = "nifvalidator";
            }

            $this->validate(request(), $rules, $messages);

            
            return $this->responseJSON([], 'register.register_success');
        } catch (\Illuminate\Validation\ValidationException $validExcept) {
            return $this->responseJSON([], $validExcept->getMessage(), 401);
        } catch (Exception $except) {            
            return $this->responseJSON([], $except->getMessage(), 401);
        }
    }
}

第二个问题是,如果我注意到控制器我在密码字段中进行了正则表达式验证以识别是否有字母或数字,我还自定义了将出现在正则表达式字段中的消息,但返回的消息总是相同的“给定数据无效。

老实说,我不知道该怎么办了,我在互联网上找到的所有东西都试过了,但都没有用。

我真的很感激帮助。

标签: phplaravellaravel-5eloquent

解决方案


如果我是正确的,错误是由于不使用 pass() pass 是您已实现的接口规则中预定义的函数,所以,我想它应该通过更改服务提供者来工作,

public function boot(): void
    {
        \Validator::extend('empty_if', function($attribute, $value, $parameters, $validator) {
            $rule = new \App\Rules\NifValidator();
            return $rule->passes();
        });
        // or you can try though I have not sure of the commented method if it works you can inform me It would be new knowledge for me.
        // \Validator::extend('nifvalidator', '\App\Rules\NifValidator@passes');
    }

如果它不起作用,您可以随时将其添加到 $messages 中(尽管这不是您所要求的,但只是第二个选项)

$messages = [
                'password.regex' => 'A password precisa ter no minimo 1 letra e 1 número',
                'nif.nifvalidator' => ':attribute inválido'
            ];

推荐阅读