簡體   English   中英

Laravel 需要兩個字段之一的驗證規則,但兩者都不應該存在

[英]Laravel validation rule for either of two fields required but both should not be present

是否有 Laravel 驗證規則適用於何時需要兩個字段中的任何一個但兩者不應同時存在。

例如。 手機號碼和 email,其中任何一個都應該存在,但不能同時存在。

不幸的是,我找不到一個。

為了滿足您的需求,以下是我采取的步驟。

  1. Laravel 有一個驗證規則,如果其他請求參數不存在,則需要一個請求參數

required_without:foo,bar,...

僅當任何其他指定字段不存在時,驗證中的字段才必須存在且不為空。

  1. 對於實現的情況,而不是兩種情況,我必須想出一個自定義驗證規則。

腳步

2a. 打開終端並運行命令以生成自定義驗證規則。 php artisan make:rule OneOf

這里OneOf是我的驗證規則名稱。 給它起任何你想要的名字。 (使用 PascalCase)。

2b。 打開生成的文件添加您的邏輯。

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;
use Illuminate\Http\Request;

class OneOf implements Rule
{
    public $oneOf = [];
    public $request = null;
    public $message = "";

    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct(Request $request, array $oneOf, string $message = "")
    {
    $this->oneOf = $oneOf;
    $this->request = $request;
    $this->message = $message;
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param string $attribute
     * @param mixed $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
    $count = 0;
    foreach ($this->oneOf as $param) {
        if($this->request->has($param)){
        $count++;
        }
    }
    return count($this->oneOf) && ($count === 1) ? true : false;

    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
    $json_encodedList = json_encode($this->oneOf);

    return  strlen(trim($this->message)) ? $this->message : "Please insert one of $json_encodedList.";
    }


}

2c。 在您的 controller 中,使用創建的自定義規則。

<?php

namespace App\Http\Controllers\Employee;

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


/**
 * Class Employee
 * @package App\Http\Controllers\Employee
 */
class Employee extends Controller
{

    public function store(Request $request)
    {

    $request->validate([
        "email" => ["required_without:phone_number", new OneOf($request, ["email", "phone_number"])],

        "phone_number" => ["required_without:email", new OneOf($request, ["email", "phone_number"])],

    ]);
    
    // ...Custom project specific logic here

    return response()->json([]);
    }
}

如果您願意,可以提供自定義消息。

您還可以將其應用於兩個以上的請求參數

我已經稍微更新了這段代碼,以確保如果它們是 null,則不計算在內。 一個請求可以有一個參數,但該參數是 null,即使提供的兩個字段之一沒有任何內容,該規則仍將作為無效觸發。

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class OneOf implements Rule
{
    public $oneOf = [];
    public $request = null;
    public $message = "";

    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct(Request $request, array $oneOf, string $message = "")
    {
        $this->oneOf = $oneOf;
        $this->request = $request;
        $this->message = $message;
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param string $attribute
     * @param mixed $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        $count = 0;
        foreach ($this->oneOf as $param) {
            if($this->request->has($param) && $this->request->$param != null){
                $count++;
            }
        }
        return count($this->oneOf) && ($count === 1) ? true : false;

    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        $i = 1;
        $length = count($this->oneOf);
        $fieldNames = null;
        foreach($this->oneOf as $fieldName) {
            if($i < $length) {
                $fieldNames .= Str::replace('_', ' ', Str::title($fieldName)) . ', ';
            } else {
                $fieldNames .= Str::replace('_', ' ', Str::title($fieldName));
            }
            $i++;
        }
        return  strlen(trim($this->message)) ? $this->message : "Only one of these fields should be used: $fieldNames.";
    }
}

您也可以通過結合required_withoutdenied_unless來實現這一點。

例如:

    [
        'email' => 'required_without:name|prohibited_unless:name,""'
        'name' => 'required_without:email|prohibited_unless:email,""'
    ]

注意:prohibited_unless 是相當新的,自 Laravel 8 起可用

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM