Como validar array no Laravel?

105

Tento validar o POST do array no Laravel:

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

        ]);

Eu envio um POST vazio e recebo if ($validator->fails()) {}como False. Significa que a validação é verdadeira, mas não é.

Como validar array no Laravel? Quando eu envio o formulário cominput name="name[]"

Darama
fonte

Respostas:

239

O símbolo de asterisco (*) é usado para verificar os valores na matriz, não a própria matriz.

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

No exemplo acima:

  • "nomes" deve ser uma matriz com pelo menos 3 elementos,
  • os valores na matriz "nomes" devem ser strings distintas (exclusivas), com pelo menos 3 caracteres.

EDITAR: Desde o Laravel 5.5 você pode chamar o método validate () diretamente no objeto Request assim:

$data = $request->validate([
    "name"    => "required|array|min:3",
    "name.*"  => "required|string|distinct|min:3",
]);
Filip Sobol
fonte
lembre-se de colocá-lo em uma trava de teste se estiver usando $request->validate([...]). Uma exceção será gerada se os dados falharem na validação.
daisura99
como obter a mensagem de erro de um campo específico? como se eu tivesse 2 campos de nome, e aí é o segundo campo que tem apenas o erro, como posso obtê-lo?
Eem Jee
38

Eu tenho esta matriz como meus dados de solicitação de uma grade / tabela de dados HTML + Vue.js:

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

E use isso para validar o que funciona corretamente:

$this->validate($request, [
    '*.item_id' => 'required|integer',
    '*.item_no' => 'required|integer',
    '*.size'    => 'required|max:191',
]);
Nisal Gunawardana
fonte
2
Este é exatamente o tipo de coisa que eu precisava!
Chris Stage de
17

A maneira recomendada de escrever lógica de validação e autorização é colocar essa lógica em classes de solicitação separadas. Dessa forma, seu código de controlador permanecerá limpo.

Você pode criar uma classe de solicitação executando php artisan make:request SomeRequest.

No rules()método de cada classe de solicitação, defina suas regras de validação:

//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
    ]
  ];
}

Em seu controlador, escreva sua função de rota assim:

// 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.
}

Cada classe de solicitação vem com ganchos / métodos de pré e pós-validação que podem ser personalizados com base na lógica de negócios e casos especiais para modificar o comportamento normal da classe de solicitação.

Você pode criar classes de solicitação pai para tipos semelhantes de solicitações (por exemplo, webe api) solicitações e, em seguida, encapsular alguma lógica de solicitação comum nessas classes pai.

sumit
fonte
6

Dados um pouco mais complexos, mistura das respostas de @Laran e @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
   }
]

A regra de validação será

 return [
            '*.customer_id' => 'required|numeric|exists:customers,id',
            '*.foodItemsList.*.id' => 'required|exists:food_items,id',
            '*.foodItemsList.*.quantity' => 'required|numeric',
        ];
Prafulla Kumar Sahu
fonte
4

Você deve fazer um loop na matriz de entrada e adicionar regras para cada entrada conforme descrito aqui: Regras de loop

Aqui está um código para você:

$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
fonte
9
Não há necessidade de fazer isso - laravel.com/docs/5.4/validation#validating-arrays
Filip Sobol