Jak zweryfikować macierz w Laravel?

110

Próbuję sprawdzić poprawność tablicy POST w Laravel:

$validator = Validator::make($request->all(), [
            "name.*" => 'required|distinct|min:3',
            "amount.*" => 'required|integer|min:1',
            "description.*" => "required|string"

        ]);

Wysyłam pusty POST i odbieram if ($validator->fails()) {}jako False. Oznacza to, że walidacja jest prawdziwa, ale tak nie jest.

Jak zweryfikować macierz w Laravel? Kiedy przesyłam formularz zinput name="name[]"

Darama
źródło

Odpowiedzi:

257

Symbol gwiazdki (*) służy do sprawdzania wartości w tablicy, a nie samej tablicy.

$validator = Validator::make($request->all(), [
    "names"    => "required|array|min:3",
    "names.*"  => "required|string|distinct|min:3",
]);

W powyższym przykładzie:

  • „nazwy” muszą być tablicą zawierającą co najmniej 3 elementy,
  • wartości w tablicy „nazwy” muszą być odrębnymi (unikalnymi) ciągami o długości co najmniej 3 znaków.

EDYCJA: Od Laravel 5.5 możesz wywołać metodę validate () bezpośrednio na obiekcie Request w następujący sposób:

$data = $request->validate([
    "name"    => "required|array|min:3",
    "name.*"  => "required|string|distinct|min:3",
]);
Filip Sobol
źródło
1
pamiętaj, aby umieścić go w try catch, jeśli używasz $request->validate([...]). Wyjątek zostanie zgłoszony, jeśli dane nie przejdą weryfikacji.
daisura99
jak uzyskać komunikat o błędzie w określonym polu? tak jak mam 2 pola nazwy, a to drugie pole ma tylko błąd, jak mogę to osiągnąć?
Eem Jee
wymagany w 'name. *' nie jest potrzebny, ponieważ sprawdza go tylko wtedy, gdy istnieje
Ben Gooding,
41

Mam tę tablicę jako dane żądania z siatki / tabeli danych HTML + Vue.js:

[0] => Array
    (
        [item_id] => 1
        [item_no] => 3123
        [size] => 3e
    )
[1] => Array
    (
        [item_id] => 2
        [item_no] => 7688
        [size] => 5b
    )

I użyj tego, aby sprawdzić, który działa poprawnie:

$this->validate($request, [
    '*.item_id' => 'required|integer',
    '*.item_no' => 'required|integer',
    '*.size'    => 'required|max:191',
]);
Nisal Gunawardana
źródło
2
Właśnie tego potrzebowałem!
Chris Stage
19

Zalecanym sposobem zapisu logiki walidacji i autoryzacji jest umieszczenie tej logiki w oddzielnych klasach żądań. W ten sposób kod kontrolera pozostanie czysty.

Możesz utworzyć klasę żądania, wykonując php artisan make:request SomeRequest.

W rules()metodzie każdej klasy żądania zdefiniuj swoje reguły walidacji:

//SomeRequest.php
public function rules()
{
   return [
    "name"    => [
          'required',
          'array', // input must be an array
          'min:3'  // there must be three members in the array
    ],
    "name.*"  => [
          'required',
          'string',   // input must be of type string
          'distinct', // members of the array must be unique
          'min:3'     // each string must have min 3 chars
    ]
  ];
}

W kontrolerze napisz funkcję trasy w ten sposób:

// SomeController.php
public function store(SomeRequest $request) 
{
  // Request is already validated before reaching this point.
  // Your controller logic goes here.
}

public function update(SomeRequest $request)
{
  // It isn't uncommon for the same validation to be required
  // in multiple places in the same controller. A request class
  // can be beneficial in this way.
}

Każda klasa żądania zawiera zaczepy / metody przed i po walidacji, które można dostosować w oparciu o logikę biznesową i przypadki specjalne w celu zmodyfikowania normalnego zachowania klasy żądania.

Możesz utworzyć nadrzędne klasy żądań dla podobnych typów żądań (np. webI api) żądań, a następnie zawrzeć pewną wspólną logikę żądań w tych klasach nadrzędnych.

sumit
źródło
6

Trochę bardziej złożone dane, mieszanka odpowiedzi @ Laran i @Nisal Gunawardana

[ 
   {  
       "foodItemsList":[
    {
       "id":7,
       "price":240,
       "quantity":1
                },
               { 
                "id":8,
                "quantity":1
               }],
        "price":340,
        "customer_id":1
   },
   {   
      "foodItemsList":[
    {
       "id":7,
       "quantity":1
    },
    { 
        "id":8,
        "quantity":1
    }],
    "customer_id":2
   }
]

Reguła walidacji będzie

 return [
            '*.customer_id' => 'required|numeric|exists:customers,id',
            '*.foodItemsList.*.id' => 'required|exists:food_items,id',
            '*.foodItemsList.*.quantity' => 'required|numeric',
        ];
Prafulla Kumar Sahu
źródło
4

Musisz zapętlić tablicę wejściową i dodać reguły dla każdego wejścia, jak opisano tutaj: Reguły pętli

Oto kod dla ciebie:

$input = Request::all();
$rules = [];

foreach($input['name'] as $key => $val)
{
    $rules['name.'.$key] = 'required|distinct|min:3';
}

$rules['amount'] = 'required|integer|min:1';
$rules['description'] = 'required|string';

$validator = Validator::make($input, $rules);

//Now check validation:
if ($validator->fails()) 
{ 
  /* do something */ 
}
Chad Fisher
źródło
9
Nie ma takiej potrzeby - laravel.com/docs/5.4/validation#validating-arrays
Filip Sobol