Comment valider un tableau dans Laravel?

105

J'essaye de valider le tableau POST dans Laravel:

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

        ]);

J'envoie un POST vide et je reçois ceci if ($validator->fails()) {}comme False. Cela signifie que la validation est vraie, mais ce n'est pas le cas.

Comment valider un tableau dans Laravel? Lorsque je soumets un formulaire avecinput name="name[]"

Darama
la source

Réponses:

239

Le symbole astérisque (*) est utilisé pour vérifier les valeurs dans le tableau, pas le tableau lui-même.

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

Dans l'exemple ci-dessus:

  • "names" doit être un tableau avec au moins 3 éléments,
  • les valeurs du tableau "names" doivent être des chaînes distinctes (uniques) d'au moins 3 caractères.

EDIT: Depuis Laravel 5.5, vous pouvez appeler la méthode validate () directement sur l'objet Request comme ceci:

$data = $request->validate([
    "name"    => "required|array|min:3",
    "name.*"  => "required|string|distinct|min:3",
]);
Filip Sobol
la source
n'oubliez pas de le placer dans une prise d'essai si vous l'utilisez $request->validate([...]). Une exception sera déclenchée si les données échouent à la validation.
daisura99
comment obtenir le message d'erreur d'un champ spécifique? comme j'ai 2 champs de nom, et puis c'est le deuxième champ qui n'a que l'erreur, comment puis-je l'atteindre?
Eem Jee
38

J'ai ce tableau comme données de demande à partir d'une grille / table de données HTML + Vue.js:

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

Et utilisez ceci pour valider ce qui fonctionne correctement:

$this->validate($request, [
    '*.item_id' => 'required|integer',
    '*.item_no' => 'required|integer',
    '*.size'    => 'required|max:191',
]);
Nisal Gunawardana
la source
2
C'est exactement le type de chose dont j'avais besoin!
Chris Stage
17

La méthode recommandée pour écrire la logique de validation et d'autorisation consiste à placer cette logique dans des classes de demande distinctes. De cette façon, votre code de contrôleur restera propre.

Vous pouvez créer une classe de requête en exécutant php artisan make:request SomeRequest.

Dans la rules()méthode de chaque classe de requête, définissez vos règles de validation:

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

Dans votre contrôleur, écrivez votre fonction d'itinéraire comme ceci:

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

Chaque classe de demande est livrée avec des hooks / méthodes de pré et post-validation qui peuvent être personnalisés en fonction de la logique métier et des cas spéciaux afin de modifier le comportement normal de la classe de demande.

Vous pouvez créer des classes de requêtes parentes pour des types de requêtes similaires (par exemple webet api), puis encapsuler une logique de requête commune dans ces classes parentes.

sumit
la source
6

Données un peu plus complexes, mélange de réponses de @ Laran et @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
   }
]

La règle de validation sera

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

Vous devez boucler sur le tableau d'entrée et ajouter des règles pour chaque entrée comme décrit ici: Règles de bouclage

Voici un code pour vous:

$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
la source
9
Il n'est pas nécessaire de le faire - laravel.com/docs/5.4/validation#validating-arrays
Filip Sobol