Bagaimana cara memvalidasi array di Laravel?

106

Saya mencoba memvalidasi array POST di Laravel:

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

        ]);

Saya mengirim POST kosong dan mendapatkan ini if ($validator->fails()) {}sebagai False. Artinya validasi itu benar, tetapi sebenarnya tidak.

Bagaimana cara memvalidasi array di Laravel? Saat saya mengirimkan formulir denganinput name="name[]"

Darama
sumber

Jawaban:

246

Simbol asterisk (*) digunakan untuk memeriksa nilai dalam larik, bukan larik itu sendiri.

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

Pada contoh di atas:

  • "nama" harus berupa larik dengan setidaknya 3 elemen,
  • nilai dalam larik "nama" harus berupa string berbeda (unik), minimal 3 karakter.

EDIT: Sejak Laravel 5.5 Anda dapat memanggil metode validate () langsung pada objek Request seperti:

$data = $request->validate([
    "name"    => "required|array|min:3",
    "name.*"  => "required|string|distinct|min:3",
]);
Filip Sobol
sumber
ingatlah untuk menempatkannya di tangkap percobaan jika Anda menggunakan $request->validate([...]). Pengecualian akan dimunculkan jika data gagal validasi.
daisura99
bagaimana cara mendapatkan pesan kesalahan dari bidang tertentu? seperti saya memiliki 2 bidang nama, dan kemudian bidang kedua yang hanya memiliki kesalahan, bagaimana saya bisa mendapatkannya?
Eem Jee
yang diperlukan pada 'nama. *' tidak diperlukan karena hanya memvalidasinya jika ada
Ben Gooding
41

Saya memiliki array ini sebagai data permintaan saya dari grid / tabel data HTML + Vue.js:

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

Dan gunakan ini untuk memvalidasi mana yang berfungsi dengan baik:

$this->validate($request, [
    '*.item_id' => 'required|integer',
    '*.item_no' => 'required|integer',
    '*.size'    => 'required|max:191',
]);
Nisal Gunawardana
sumber
2
Inilah jenis hal yang saya butuhkan!
Chris Stage
18

Cara yang disarankan untuk menulis logika validasi dan otorisasi adalah dengan meletakkan logika tersebut di kelas permintaan terpisah. Dengan cara ini kode pengontrol Anda akan tetap bersih.

Anda dapat membuat kelas permintaan dengan menjalankan php artisan make:request SomeRequest.

Di setiap rules()metode kelas permintaan, tentukan aturan validasi Anda:

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

Di pengontrol Anda, tulis fungsi rute Anda seperti ini:

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

Setiap kelas permintaan dilengkapi dengan hook / metode pra dan pasca-validasi yang dapat disesuaikan berdasarkan logika bisnis dan kasus khusus untuk mengubah perilaku normal kelas permintaan.

Anda dapat membuat kelas permintaan induk untuk jenis permintaan serupa (misalnya webdan api) permintaan dan kemudian merangkum beberapa logika permintaan umum di kelas induk ini.

sumit
sumber
6

Data yang sedikit lebih kompleks, campuran jawaban @ Laran dan @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
   }
]

Aturan validasinya adalah

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

Anda harus melakukan loop pada array input dan menambahkan aturan untuk setiap input seperti yang dijelaskan di sini: Aturan Loop Over

Berikut adalah beberapa kode untuk Anda:

$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
sumber
9
Tidak perlu melakukan itu - laravel.com/docs/5.4/validation#validating-arrays
Filip Sobol