ولیدیشن در لاراول 7 به همراه مثال

موضوع امروز باورژن اعتبارسنجی هست. لاراول روش‌های مختلفی برای اعتبارسنجی داده‌های اپلیکیشن فراهم کرده است. داخل پرانتز این توضیح را بدهیم که کلاس کنترلر پایه لاراول از تریت ValidatesRequests استفاده می‌کند که متد مناسبی برای اعتبارسنجی درخواست HTTP ورودی با انواع ruleهای اعتبارسنجی قدرتمند ارائه می‌دهد.

نصب لاراول

نصب کردن لاراول 7 نیاز به دستور زیر دارد.

composer create-project --prefer-dist laravel/laravel laravel7

// or

laravel new laravel7

ساخت کنترلر

یک فایل FormController.php ایجاد کنید.

php artisan make:controller FormController

دو متد در فایل FormController.php اضافه کنید.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class FormController extends Controller
{
    public function create()
    {

    }

    public function store(Request $request)
    {
        
    }
}

افزودن روت

حالا دو روت  داخل فایل routes >> web.php اضافه کنید.

// web.php

Route::get('form', 'FormController@create')->name('form.create');
Route::post('form', 'FormController@store')->name('form.store');

ایجاد مدل و مایگریشن

با استفاده از دستور زیر فایل model و migration را ایجاد کنید.

php artisan make:model Form -m

کد زیر را در فایل create_forms_table.php قرار دهید.

public function up()
{
        Schema::create('forms', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('item_name');
            $table->string('sku_no');
            $table->integer('price');
            $table->timestamps();
        });
}

با دستور زیر جدول را  ایجاد کنید.

php artisan migrate

با استفاده از فیلد $fillable فیلدهای مجاز برای مقداردهی دستی را مشخص کنید.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Form extends Model
{
    protected $fillable = ['item_name', 'sku_no', 'price'];
}

ساخت ویوها

در پوشه views فایل layout.blade.php را ایجاد کنید و کدهای زیر را در آن کپی کنید.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Laravel 6 Validation Example</title>
  <link href="{{ asset('css/app.css') }}" rel="stylesheet" type="text/css" />
</head>
<body>
  <div class="container">
    @yield('content')
  </div>
  <script src="{{ asset('js/app.js') }}" type="text/js"></script>
</body>
</html>

در همان پوشه views فایل create.blade.php را ایجاد کنید و کدهای زیر را در آن کپی کنید.

@extends('layout')

@section('content')
<style>
  .uper {
    margin-top: 40px;
  }
</style>
<div class="card uper">
  <div class="card-header">
    Add Item
  </div>
  <div class="card-body">
      <form method="post" action="{{ route('form.store') }}">
          <div class="form-group">
              @csrf
              <label for="name">Item Name:</label>
              <input type="text" class="form-control" name="item_name"/>
          </div>
          <div class="form-group">
              <label for="price">SKU Number :</label>
              <input type="text" class="form-control" name="sku_no"/>
          </div>
          <div class="form-group">
              <label for="quantity">Item Price :</label>
              <input type="text" class="form-control" name="price"/>
          </div>
          <button type="submit" class="btn btn-primary">Create Item</button>
      </form>
  </div>
</div>
@endsection

متد create() را در کنترلر FormControllerتعریف کنید.

// FormController.php

public function create()
{
    return view('create');
}

خب الان باید از طریق لینک http://localhost:8000/form به فرم دسترسی داشته باشید.

نوشتن لاجیک ولیدیشن

توجه

ولیدیشن (Validation) یا اعتبارسنجی به عملیات بررسی فیلدهای فرم طبق ruleهای تعریف شده می‌گویند. در واقع حتی اگر یکی از فیلدها حتی یک ولیدیشن را رعایت نکند می‌گوییم ولیدیشن fail شده یا شکست خورده و باید مجددا فرم را به همراه دلیل شکست اعتبارسنجی به کاربر نمایش دهیم.

در متد store() کنترلر FormController لاجیک اعتبارسنجی را بنویسید.

public function store(Request $request)
{
        $validatedData = $request->validate([
            'item_name' => 'required|max:255',
            'sku_no' => 'required|alpha_num',
            'price' => 'required|numeric',
        ]);
        \App\Form::create($validatedData);

        return response()->json('Form is successfully validated and data has been saved');
}

حالا به فرم بروید و دیتا وارد کنید و سعی کنید فرم را ارسال کنید. فرم ارسال نمی‌شود اما خطایی هم نمی‌بینید.!!

نمایش خطاهای اعتبار سنجی

این snippet را باید در فایل create.blade.php بنویسیم.

@if ($errors->any())
      <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
              <li>{{ $error }}</li>
            @endforeach
        </ul>
      </div><br />
@endif

اگر پارامترهای فرم ارسالی، قوانین اعتبارسنجی را رعایت نکرده باشند، لاراول اتوماتیک وار کاربر را به مکان قبلی خود هدایت می‌کند.

تمام خطاهای اعتبارسنجی در یک سشن یکبار مصرف ذخیره می‌شوند.

توجه

نکته‌ای که در اینجا باید توجه کنیم این است که ما مجبور نبودیم به طور صریح تمام پیام‌های خطا را به یک view در روت GET وصل کنیم. دلیل این امر این است که لاراول خطاهای موجود در سشن داده را چک می‌کند و در صورت موجود بودن، به صورت خودکار آن‌ها را به یک view وصل می‌کند.

متغیر errors$ مثالی از Illuminate\Support\MessageBag خواهد بود.
در نهایت کدهای فایل create.blade.php را در ادامه داریم.

@extends('layout')

@section('content')
<style>
  .uper {
    margin-top: 40px;
  }
</style>
<div class="card uper">
  <div class="card-header">
    Add Item
  </div>
  <div class="card-body">
    @if ($errors->any())
      <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
              <li>{{ $error }}</li>
            @endforeach
        </ul>
      </div><br />
    @endif
      <form method="post" action="{{ route('form.store') }}">
          <div class="form-group">
              @csrf
              <label for="name">Item Name:</label>
              <input type="text" class="form-control" name="item_name"/>
          </div>
          <div class="form-group">
              <label for="price">SKU Number :</label>
              <input type="text" class="form-control" name="sku_no"/>
          </div>
          <div class="form-group">
              <label for="quantity">Item Price :</label>
              <input type="text" class="form-control" name="price"/>
          </div>
          <button type="submit" class="btn btn-primary">Create Item</button>
      </form>
  </div>
</div>
@endsection

دایرکتیو @error

از دایرکتیو بلید @error می‌توانید خیلی سریع بررسی کنید که آیا پیام‌های خطای ولیدیشن برای اتریبیوت خاصی وجود دارند یا خیر.  در دایرکتیو @error، می‌توانید از متغییر $message برای نمایش پیام خطا استفاده کنید.

<div class="form-group">
   @csrf
   <label for="name">Item Name:</label>
   <input type="text" class="form-control" name="item_name"/>
    @error('item_name')
          <div class="alert alert-danger">{{ $message }}</div>
    @enderror
</div>

فیلدهای اختیاری

لاراول به صورت پیش‌فرض میدلورهای TrimStrings و ConvertEmptyStringsToNull را در آرایه گلوبال میدلورهای اپلیکیشن قرار می‌دهد.

این میدلورها بوسیله کلاس App\Http\Kernel در استک اینکلود می‌شوند.

دلیل استفاده از این میدلورها این است که اگر نمی‌خواهید ولیدیتور مقادیر null را غیرمجاز در نظر بگیرید، اغلب باید فیلدهای اختیاری ریکوئست را nullable قرار دهید.

برای مثال:

$request->validate([
    'item_name' => 'required|max:255',
    'sku_no' => 'required|alpha_num',
    'price' => 'required|numeric',
    'publish_at' => 'nullable|date',
]);

در این مثال، انتظار داریم فیلد publish_at مقدار null یا تاریخی مجاز را داشته باشد.

اگر مدیفایر nullable به تعریف rule اضافه نشود، ولیدیتور مقدار null را تاریخی غیرمجاز در نظر می‌گیرد.

ریکوئست‌های اجکس و ولیدیشن

در این مثال، از فرم ساده برای ارسال داده به یک اپلیکیشن استفاده کرده‌ایم.

با این حال، بسیاری از اپلیکیشن‌ها از ریکوئست‌های اجکس استفاده می‌کنند.

هنگامی که از متد validate() برای ریکوئست اجکسی استفاده می‌کنید، لاراول ریسپانس ریدایرکت تولید نخواهد کرد.

در عوض، لاراول ریسپانس JSON حاوی تمامی خطاهای ولیدیشن تولید می‌کند. ریسپانس JSON به همراه کد هدر 422 ارسال خواهد شد.

ولیدیشن فرم ریکوئست

برای مواردی با ولیدیشن‌های پیچیده‌تر، می‌توانید از فرم ریکوئست استفاده کنید.

نکته

توصیه می‌کنیم تا حد امکان حتما تمامی ولیدیشن‌ها را از طریق Form Request انجام دهید.

فرم ریکوئست‌ها، کلاس‌های ریکوئست سفارشی هستند که حاوی تمام لاجیک مربوط به ولیدیشن هستند.

اگر نیاز به ساخت کلاس فرم ریکوئست دارید، از کامند آرتیزان make:request استفاده کنید:

php artisan make:request ValidateRequest

کلاس ایجاد شده در دایرکتوری app/Http/Requests قرار دارد.

اگر این دایرکتوری وجود نداشت، هنگامی که کامند make:request را اجرا کنید، ایجاد خواهد شد.

بیاید کمی قوانین اعتبارسنجی به متد rules اضافه کنیم:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class ValidateRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'item_name' => 'required|max:255',
            'sku_no' => 'required|alpha_num',
            'price' => 'required|numeric',
        ];
    }
}

شاید برای شما هم این سوال پیش بیاید که قوانین اعتبار سنجی چگونه ارزیابی می‌شوند؟

در جواب این سوال می‌توان گفت، تنها کاری که باید باید انجام دهید این است که یک ریکوئست در متد کنترلر خود تایپ کنید.

قبل از فراخوانی متد کنترلر، ریکوئست فرم ارسالی ولیدیت می‌شود، به این معنی كه نیازی به قرار دادن هیچ لاجیکی در کنترلر نداریم.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests\ValidateRequest;

class FormController extends Controller
{
    public function create()
    {
        return view('create');
    }

    public function store(ValidateRequest $request)
    {
        $validatedData = $request->validated();
        \App\Form::create($validatedData);

        return response()->json('Form is successfully validated and data has been saved');
    }
}

ایجاد اعتبار سنجی دستی

چنانچه نمی‌خواهید از متد validate() در ریکوئست استفاده کنید، می‌توانید آبجکت اعتبارسنجی را با استفاده از فساد Validator به صورت دستی ایجاد کنید.

متد make فساد Validator، نمونه یا instance جدیدی را ایجاد می‌کند.
این کدها را در فایل FormController.php قرار دهید.

public function store(ValidateRequest $request)
{
        $validator = \Validator::make($request->all(), [
            'item_name' => 'required|max:255',
            'sku_no' => 'required|alpha_num',
            'price' => 'required|numeric',
        ]);

        if ($validator->fails()) {
            return redirect('form')
                        ->withErrors($validator)
                        ->withInput();
        }

        \App\Form::create([
            'item_name' => $request->item_name, 
            'sku_no' => $request->sku_no,
            'price' => $request->sku_no
        ]);

        return response()->json('Form is successfully validated and data has been saved');
}

اولین آرگومنتی که به متد make پاس داده می‌شود، دیتایی است که می‌خواهیم روی آن ولیدیشن انجام دهیم.

آرگومنت دوم قوانین اعتبارسنجی است که باید برای داده‌ها اعمال شود.

پس از بررسی در صورت عدم تایید اعتبارسنجی داده‌ها، می‌توانید از متد withErrors برای قرار دادن پیام‌های خطا در یک سشن استفاده کنید.

هنگام استفاده از این متد، متغیر $errors پس از تغییر مسیر، به طور خودکار با ویوها به اشتراک گذاشته می‌شود و این امکان را فراهم می‌کند تا آنها را به راحتی به فرم بازگردانیم و به کاربر نمایش دهیم.

متد withErrors نمونه ساخته شده از Validator یا MessageBag یا یک آرایه PHP را می‌پذیرد.

نامگذاری Error Bagها

اگر فرم‌های مختلفی در یک صفحه دارید، ممکن است بخواهید پیام خطاهای MessageBag را نامگذاری کنید. این کار به ما این امکان را می‌دهد که پیام‌های خطا را برای فرم خاص بازیابی کنیم.

name را به عنوان دومین آرگومان به withErrors بدهید:

return redirect('register')
            ->withErrors($validator, 'login');

بعد از این می‌توانید با استفاده از متغیر $errors به MessageBag دسترسی داشته باشید.

{{ $errors->login->first('email') }}

کار کردن با Error Messages

بعد از فراخوانی متد errors نمونه ایجاد شده از Validator، نمونه ایجاد شده از Illuminate\Support\MessageBag ریترن می‌شود که متدهای  متنوعی و کاربردی زیادی برای کار با پیام‌های خطا دارد.

متغیر $errors که بطور خودکار در همه ویوها در دسترس است نیز نمونه ساخته شده از کلاس MessageBag است.

بازیابی اولین پیام خطا برای فیلد

برای اینکه اولین پیام خطا را برای یک فیلد را بازیابی کنیم، از متد first استفاده می‌کنیم:

$errors = $validator->errors();

echo $errors->first('email');

بازیابی تمام پیام‌های خطا برای فیلد

اگر بخواهیم تمام پیام‌های خطای یک فیلد را بازیابی کنیم، از متد get استفاده می‌کنیم.

foreach ($errors->get('email') as $message) {
    //
}

اگر اعتبارسنجی آرایه‌ای از فیلد فرم را بررسی می‌کنید، امکان بازیابی تمام پیغام‌ها با کارکتر * وجود دارد.

foreach ($errors->get('attachments.*') as $message) {
    //
}

خب در این مقاله گزینه‌های متعددی برای اعتبارسنجی فرم در لاراول 7 را با هم بررسی کردیم. امیدواریم که این مقاله از باورژن برای شما مفید واقع شده باشد.

رقیه اباذری

رقیه اباذری

تو دانشگاه IT خوندم و اکثر منابع کتاب‌های ترجمه شده بودند و صدالبته مبهم :( مثلا element رو "عنصر" ترجمه می‌کردن و من همیشه می‌رفتم تو شیمی و جدول مندلیف. تو باورژن سعی کردم تا حد ممکن مطالب رو با زبان ساده و قابل درک بنویسم. باشد که کسانی که تازه پا به عرصه برنامه‌نویسی گذاشتن، راغب‌تر بشن و با نظرات و فیدبک‌های شما راه هموارتر بشه:)

دیدگاه‌ها


ثبت دیدگاه