validation یا اعتبارسنجی در لاراول

اصول آموزش Laravel

تاریخ : یکشنبه 22 بهمن 1396

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


شروع اعتبارسنجی در لاراول

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


تعریف مسیرها

ابتدا فرض می‌کنیم، مسیرهای زیر در فایل routes/web.php تعریف شده‌اند:

Route::get('post/create', '[email protected]');

Route::post('post', '[email protected]');

مسیر GET یک فرم برای کاربر نمایش می‌دهد که بتواند یک پست جدید ایجاد کند، در حالی که، مسیر POST پست جدید را در پایگاه داده ذخیره می‌کند.


ایجاد کنترلر

پس، یک کنترلر ساده که این مسیرها را مدیریت می‌کند را در نظر می‌گیریم. فعلاً، متد store را به صورت خالی نگه می‌‌داریم:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class PostController extends Controller
{
    /**
     * Show the form to create a new blog post.
     *
     * @return Response
     */
    public function create()
    {
        return view('post.create');
    }

    /**
     * Store a new blog post.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        // Validate and store the blog post...
    }
}


پیاده سازی منطق اعتبارسنجی

اکنون می‌توانیم، متد store را با کدهای اعتبارسنجی جهت تأیید اعتبار پست جدید کاربر پر کنیم. برای انجام این کار، از متد validate که توسط شئ Illuminate\Http\Request ارائه شده، استفاده می‌کنیم.

اگر قوانین اعتبارسنجی تصویب شوند، کد در حالت نرمال به اجرا ادامه می‌دهد؛ با این حال، اگر اعتبارسنجی با خطا روبرو شود، یک استثنا یا exception پرتاب شده و به صورت خودکار پاسخ خطای مناسب به کاربر ارسال می‌شود. در مورد درخواست‌های HTTP سنتی، یک پاسخ redirect تولید می‌شود و کاربر را به صفحه قبل بازگشت می‌دهد، در حالی که در مورد درخواست‌های AJAX یک پاسخ JSON به کاربر ارسال می‌شود.

برای درک بهتر متد validate ، اجازه دهید نگاهی دوباره به متد store بیاندازیم:

/**
 * Store a new blog post.
 *
 * @param  Request  $request
 * @return Response
 */
public function store(Request $request)
{
    $validatedData = $request->validate([
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ]);

    // The blog post is valid...
}

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


توقف اجرا در اولین شکست اعتبارسنجی

گاهی اوقات ممکن است بخواهید، پس از اولین شکست در عملیات اعتبارسنجی یک صفت، اجرای قوانین اعتبارسنجی بعدی را بر روی آن صفت متوقف کنید. برای انجام این کار، باید قانون bail را به آن صفت اختصاص دهید:

$request->validate([
    'title' => 'bail|required|unique:posts|max:255',
    'body' => 'required',
]);

در این مثال، اگر قانون unique در صفت title با شکست مواجه شود، قانون max بررسی نخواهد شد. قوانین به ترتیبی که مشخص شده‌اند، اعتبارسنجی می‌شوند.


صفت‌های تودرتو (nested attributes) در پارامترهای درخواست

اگر درخواست HTTP، شامل پارامترهای تودوتو (nested) باشد، در قوانین اعتبارسنجی می‌توان آن‌ها را با استفاده از علامت «نقطه» مشخص کرد:

$request->validate([
    'title' => 'required|unique:posts|max:255',
    'author.name' => 'required',
    'author.description' => 'required',
]);


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

اگر پارامترهای درخواست ورودی با قوانین اعتبارسنجی داده شده مطابقت نداشته باشند، چکار باید کرد؟ همانطور که قبلاً ذکر شد، لاراول به صورت خودکار کاربر را به مکان قبلی هدایت خواهد کرد. علاوه بر این، تمام خطاهای اعتبارسنجی به صورت خودکار در سشن نوشته می‌شوند.

نباید به صورت صریح پیام‌های خطا را در مسیر GET به view بایند کنیم. به این دلیل که لاراول خطاها را در داده‌های سشن بررسی می‌کند و اگر آن‌ها در دسترس باشند، به صورت خودکار آن‌ها را به view بایند می‌کند. متغیر $errors یک نمونه از کلاس Illuminate\Support\MessageBag است.

متغیر $errors توسط میدلور Illuminate\View\Middleware\ShareErrorsFromSession به view بایند می‌شود که به وسیله گروه middleware web ارائه می‌شود. زمانی که این middleware اعمال می‌شود متغیر $errors همواره در view در دسترس خواهد بود و در هر زمانی می‌توان از آن استفاده کرد.

بنابراین، در این مثال، زمانی که اعتبارسنجی ناموفق باشد، کاربر به متد create کنترلر برگردانده می‌شود و می‌توانیم پیام‌های خطا را در view به کاربر نمایش دهیم:

<!-- /resources/views/post/create.blade.php -->

<h1>Create Post</h1>

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

<!-- Create Post Form -->


فیلدهای اختیاری در اعتبارسنجی

لاراول به صورت پیش‌فرض شامل میدلورهای TrimStrings و ConvertEmptyStringsToNull در پشته middleware عمومی برنامه است. این middlewarelها توسط کلاس App\Http\Kernel در پشته لیست شده‌اند. به همین دلیل، اگر بخواهید مقادیر null توسط عملیات اعتبارسنجی یک مقدار نامعتبر در نظر گرفته نشوند، باید فیلد‌های درخواست اختیاری را به عنوان nullable علامتگذاری کنید. به مثال زیر توجه کنید:

$request->validate([
    'title' => 'required|unique:posts|max:255',
    'body' => 'required',
    'publish_at' => 'nullable|date',
]);

در این مثال، فیلد publish_at مشخص شده است که می‌تواند شامل یک مقدار null یا یک نمایش تاریخ معتبر باشد. اگر اصلاح کننده nullable به تعریف قانون اعتبارسنجی اضافه نشود، validator مقدار null را یک تاریخ نامعتبر در نظر می‌گیرد.


درخواست‌های AJAX در اعتبارسنجی

در این مثال، ما از یک فرم سنتی استفاده کردیم. با این حال، بسیاری از برنامه‌های کاربردی از درخواست‌های AJAX برای ارسال داده‌ها به برنامه استفاده می‌کنند. هنگام استفاده از متد validate در طول یک درخواست AJAX، لاراول یک پاسخ redirect به صفحه قبل ایجاد نمی‌کند. به جای این کار، لاراول یک پاسخ JSON شامل تمام خطاهای اعتبارسنجی ایجاد می‌کند. این پاسخ JSON با یک کد وضعیت 422 HTTP به کاربر ارسال می‌شود.


اعتبارسنجی توسط form request

برای نوشتن سناریوهای پیچیده جهت اعتبارسنجی داده‌ها، می‌توانید یک درخواست فرم یا form request ایجاد کنید. درخواست‌های فرم، کلاس‌های درخواست سفارشی هستند که منطق اعتبارسنجی را در درون خود جای می‌دهند. برای ایجاد یک کلاس form request، می‌توان از دستور آرتیسان make:request به صورت زیر استفاده کرد:

php artisan make:request StoreBlogPost

کلاس ایجاد شده در دایرکتوری app/Http/Requests قرار می‌گیرد. اگر این دایرکتوری موجود نباشد، در زمان اجرای دستور make:request ایجاد خواهد شد. اجازه دهید، چند قانون اعتبارسنجی را به متد rules اضافه کنیم:

/**
 * Get the validation rules that apply to the request.
 *
 * @return array
 */
public function rules()
{
    return [
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ];
}

چگونه می‌توان قوانین اعتبارسنجی را ارزیابی کرد؟ تمام آن چیزی که باید انجام داد، این است که form request را در متد کنترلر اعلان نوع یا type-hint کنید. درخواست فرم ورودی قبل از فراخوانی متد کنترلر اعتبارسنجی می‌شود. به ایم معنی که دیگر نیازی به وارد کردن منطق اعتبارسنجی خود در درون کلاس کنترلر نخواهید داشت:

/**
 * Store the incoming blog post.
 *
 * @param  StoreBlogPost  $request
 * @return Response
 */
public function store(StoreBlogPost $request)
{
    // The incoming request is valid...
}

اگر عملیات اعتبارسنجی ناموفق باشد، یک پاسخ redirect ایجاد شده و کاربر را به صفحه قبل برمی‌‌گرداند. خطاها نیز در سشن flash می‌شوند (نوشته می‌شوند) تا برای نمایش دادن به کاربر در دسترس قرا گیرند. اگر درخواست ورودی یک درخواست AJAX باشد، یک پاسخ HTTP با کد وضعیت 422، شامل یک نمایش JSON از خطاهای اعتبارسنجی به کاربر نمایش داده خواهد شد.


اضافه کردن after hook به form request

اگر بخواهید یک hook after را به form request اضافه کنید، می‌توانید از متد withValidator استفاده کنید. این متد اعتبارسنجی ایجاد شده را به صورت کامل دریافت می‌کند و این امکان را می‌دهد که قبل از ارزیابی قوانین اعتبارسنجی به صورت واقعی، بتوانید متدهایش را فراخوانی کنید:

/**
 * Configure the validator instance.
 *
 * @param  \Illuminate\Validation\Validator  $validator
 * @return void
 */
public function withValidator($validator)
{
    $validator->after(function ($validator) {
        if ($this->somethingElseIsInvalid()) {
            $validator->errors()->add('field', 'Something is wrong with this field!');
        }
    });
}


احراز هویت Form Request

کلاس form request نیز شامل یک متد authorize است. می‌توانید در این متد، مجوز کاربر احراز هویت شده به ویرایش یک منبع داده شده را بررسی کنید. برای مثال، می‌توانید تعیین کنید که آیا کاربر کامنتی بر روی یک پست دارد که می‌خواهد آن را ویرایش کند؟

/**
 * Determine if the user is authorized to make this request.
 *
 * @return bool
 */
public function authorize()
{
    $comment = Comment::find($this->route('comment'));

    return $comment && $this->user()->can('update', $comment);
}

از آنجایی که تمام form requestها، از کلاس request لاراول ارث‌ بری می‌کنند، می‌توان از متد user برای دسترسی به کاربری که در حال حاضر احراز هویت شده است، استفاده کرد. به فراخوانی متد route در مثال بالا توجه کنید، این متد امکان می‌دهد که به پارامترهای URI تعریف شده در فراخوانی مسیر مانند پارامتر {comment} در مثال زیر دسترسی داشته باشید:

Route::post('comment/{comment}');

اگر متد authorize مقدار false را برگرداند، یک پاسخ HTTP با کد وضعیت 403 به صورت خودکار بازگردانده می‌شود و متد کنترلر اجرا نمی‌شود.

اگر قصد دارید منطق احراز هویت را در قسمت دیگری از برنامه خود بگنجانید، می‌‌توانید به راحتی مقدار true را از متد authorize برگردانید:

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


سفارشی سازی پیام‌های خطای اعتبارسنجی

می‌توان پیام‌های خطای مورد استفاده در form request را با بازنویسی متد messages سفارشی کرد. این متد باید آرایه‌ای از صفت و قانون اعتبارسنجی آن و همچنین پیام‌های خطای مربوط به آن‌ها را بازگرداند:

/**
 * Get the error messages for the defined validation rules.
 *
 * @return array
 */
public function messages()
{
    return [
        'title.required' => 'A title is required',
        'body.required'  => 'A message is required',
    ];
}


ایجاد اعتبارسنجی به صورت دستی در لاراول

اگر نمی‌خواهید از متد validate در درخواست استفاده کنید، می‌توانید یک نمونه اعتبارسنجی را به صورت دستی با استفاده از facade Validator ایجاد کنید. متد make در facade یک نمونه validator جدید ایجاد می‌کند:

<?php

namespace App\Http\Controllers;

use Validator;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class PostController extends Controller
{
    /**
     * Store a new blog post.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'title' => 'required|unique:posts|max:255',
            'body' => 'required',
        ]);

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

        // Store the blog post...
    }
}

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

پس از بررسی داده، اگر اعتبارسنجی ناموفق باشد؛ می‌توان از متد withErrors برای flash کردن پیام‌های خطا در session استفاده کرد. هنگام استفاده از این متد متغیر $errors به صورت خودکار با viewهای برنامه پس از redirect شدن، به اشتراک گذاشته می‌شود که امکان می‌دهد به سادگی بتوانید، آن‌ها را به کاربر نمایش دهید. متد withErrors یک validator، MessageBag یا یک array می‌پذیرد.


تغییر مسیر اتوماتیک (automatic redirection) در اعتبارسنجی لاراول

اگر می‌خواهید، به صورت دستی یک نمونه validator ایجاد کنید، اما هنوز هم از تغییرمسیر (redirect) خودکار ارائه شده توسط متد validate درخواست استفاده می‌کنید، می‌توانید متد validate را بر روی نمونه validator موجود فراخوانی کنید. اگر اعتبارسنجی ناموفق باشد، کاربر به صورت خودکار redirect می‌شود (به صفحه قبلی برمی‌گردد) و یا در صورت استفاده از درخواست AJAX یک پاسخ JSON به شما ارائه خواهد داد:

Validator::make($request->all(), [
    'title' => 'required|unique:posts|max:255',
    'body' => 'required',
])->validate();


بسته‌های خطای نامگذاری شده (Named Error Bags)

اگر چند فرم در یک صفحه داشته باشید، می‌توانید MessageBag خطاها را نامگذاری کنید که امکان اینکه پیام‌های خطا را برای یک فرم خاص بازیابی کنید را فراهم می‌کند. جای نگرانی نیست، می‌توانید نام مشخص شده را به عنوان آرگومان دوم به withErrors انتقال دهید:

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

پس از آن، می‌توانید به نمونه MessageBag از متغیر $errors دسترسی داشته باشید:

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


After Validation Hook

همچنین validator اجازه می‌دهد تا پس از کامل شدن عملیات اعتبارسنجی، attach callbacks را اجرا کنید. این موضوع این امکان را می‌دهد که بتوانید به راحتی اعتبارسنجی بیشتری انجام دهید و حتی پیام‌های خطای بیشتری را به مجموعه پیام‌‌های خطا اضافه کنید. برای شروع کار، می‌توانید از متد after بر روی یک نمونه validator استفاده کنید:

$validator = Validator::make(...);

$validator->after(function ($validator) {
    if ($this->somethingElseIsInvalid()) {
        $validator->errors()->add('field', 'Something is wrong with this field!');
    }
});

if ($validator->fails()) {
    //
}


کار با پیام‌های خطا در اعتبارسنجی لاراول

پس از فراخوانی متد errors بر روی یک نمونه Validator ، یک نمونه کلاس Illuminate\Support\MessageBag دریافت خواهید کرد که متدهای مختلفی را برای کار با پیام‌های خطا ارائه می‌دهد. متغیر $errors که به صورت خودکار برای همه viewها در دسترس است نیز نمونه‌ای از کلاس MessageBag است.


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

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

$errors = $validator->errors();

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


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

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

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

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

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


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

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

foreach ($errors->all() as $message) {
    //
}


تعیین وجود پیام خطا برای یک فیلد

متد has برای تعیین اینکه آیا پیام‌ خطا برای یک فیلد مشخص وجود دارد یا خیر، استفاده می‌شود:

if ($errors->has('email')) {
    //
}


پیام‌های خطای سفارشی در اعتبارسنجی لاراول

در صورت نیاز، می‌توانید به جای استفاده از حالت پیش‌فرض، پیام‌های خطای اعتبارسنجی را به صورت سفارشی ایجاد کنید. چندین راه برای ایجاد پیام‌های خطا به صورت سفارشی وجود دارد. در روش اول، می‌توانید پیام‌های خطای سفارشی را به عنوان آرگومان سوم به Validator::make انتقال دهید:

$messages = [
    'required' => 'The :attribute field is required.',
];

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

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

$messages = [
    'same'    => 'The :attribute and :other must match.',
    'size'    => 'The :attribute must be exactly :size.',
    'between' => 'The :attribute value :input is not between :min - :max.',
    'in'      => 'The :attribute must be one of the following types: :values',
];


تعیین پیام خطای سفارشی برای یک صفت مشخص

گاهی اوقات ممکن است بخواهید، فقط برای یک فیلد خاص پیام‌های خطای سفارشی ایجاد کنید. این کار را می‌توانید با استفاده از علامت «نقطه» انجام دهید. ابتدا، اسم صفت را مشخص کنید و به دنبال آن از قانون اعتبارسنجی استفاده کنید:

$messages = [
    'email.required' => 'We need to know your e-mail address!',
];


تعیین پیام‌های خطای سفارشی در فایل‌های language

در اغلب موارد، به جای انتقال مستقیم پیام‌های خطای سفارشی خود به validator می‌توانید آن‌ها را در یک فایل language قرار دهید. برای انجام این کار، پیام‌های خود را به آرایه custom در فایل resources/lang/xx/validation.php اضافه کنید.

'custom' => [
    'email' => [
        'required' => 'We need to know your e-mail address!',
    ],
],


مشخص کردن صفت سفارشی در فایل‌های language

اگر بخواهید بخش :attribute از پیام اعتبارسنجی با یک نام attribute سفارشی جایگزین شود، می‌توانید نام سفارشی خود را در آرایه attributes از فایل resources/lang/xx/validation.php مشخص کنید:

'attributes' => [
    'email' => 'email address',
],


Available Validation Rules

در این فهرست، لیستی از قوانین اعتبارسنجی موجود در لاراول و توابع آن‌ها را مشاهده می‌کنید:


accepted

فیلدی که اعتبارسنجی می‌شود، باید دارای مقادیر yes ، on ، 1 ، یا true باشد. این قانون برای اعتبارسنجی پذیرش «شرایط استفاده از خدمات» مفید است.


active_url

فیلدی که اعتبارسنجی می‌شود، باید دارای یک رکورد معتبر A یا AAAA براساس تابع پی اچ پی dns_get_record باشد.


after:date

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

'start_date' => 'required|date|after:tomorrow'

به جای انتقال یک رشته شامل تاریخ که توسط تابع strtotime ارزیابی می‌شود، می‌توانید یک فیلد دیگر برای مقایسه با تاریخ معین، مشخص کنید:

'finish_date' => 'required|date|after:start_date'


after_or_equal:date

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


alpha

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


alpha_dash

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


alpha_num

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


array

فیلدی که اعتبارسنجی می‌شود، باید یک آرایه PHP باشد.


before:date

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


before_or_equal:date

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


between:min,max

اندازه فیلدی که اعتبارسنجی می‌شود، باید بین مقادیر min و max باشد. رشته‌ها، اعداد، آرایه‌ها، و فایل‌ها با همان روش قانون size ارزیابی می‌شوند.


boolean

فیلدی که اعتبارسنجی می‌شود، باید قابل تبدیل به یک مقدار boolean باشد. ورودی قابل قبول می‌تواند مقادیر true ، false ، 1 ، 0 ، “ 1 ” و “ 0 ” باشد.


confirmed

فیلدی که اعتبارسنجی می‌شود، باید با فیلد foo_confirmation مطابقت داشته باشد. برای مثال، اگر فیلدی که اعتبارسنجی می‌شود، فیلد password باشد، باید یک فیلد password_confirmation مربوط به آن در ورودی باشد.


date

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


date_equals:date

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


date_format:format

فرمت فیلد تاریخ مورد اعتبارسنجی، باید با فرمت داده شده مطابقت داشته باشد. هنگام اعتبارسنجی یک فیلد، باید از date یا date_format استفاده کنید، نمی‌توان از هر دو آن‌ها به صورت همزمان استفاده کرد.


different:field

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


digits:value

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


digits_between:min,max

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


dimensions

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

'avatar' => 'dimensions:min_width=100,min_height=200'

محدودیت‌های موجود عبارتند از: min_width، max_width، min_height، max_height، width، height، ratio.

محدودیت ratio باید به صورت عرض تقسیم بر ارتفاع باشد. این را می‌توان با یک عبارت مانند 3/2 یا یک مقدار اعشاری مانند 1.5 مشخص کرد:

'avatar' => 'dimensions:ratio=3/2'

از آنجا که این قانون مستلزم دریافت چند آرگومان است، می‌توانید از متد Rule::dimensions استفاده کنید تا به راحتی بتوانید قانون اعتبارسنجی خود را بسازید:

use Illuminate\Validation\Rule;

Validator::make($data, [
    'avatar' => [
        'required',
        Rule::dimensions()->maxWidth(1000)->maxHeight(500)->ratio(3 / 2),
    ],
]);


distinct

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

'foo.*.id' => 'distinct'


email

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


exists:table,column

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


مثالی ساده از قانون اعتبارسنجی exists

'state' => 'exists:states'


مشخص کردن نام سفارشی برای یک ستون

'state' => 'exists:states,abbreviation'

می‌توان یک database connection خاص مشخص کرد که می‌توان از آن در کوئری exists استفاده کرد. این کار را می‌توان با اضافه کردن نام connection توسط علامت «نقطه» به نام جدول انجام داد:

'email' => 'exists:connection.staff,email'

اگر بخواهید، اجرای کوئری را توسط قانون اعتبارسنجی سفارشی کنید، می‌توانید از کلاس Rule استفاده کنید تا به راحتی قانون مورد نظر را تعریف کنید. در این مثال، به جای آنکه از کاراکتر | برای ایجاد محدودیت در قوانین اعتبارسنجی استفاده کنیم، آن‌ها را به صورت یک آرایه مشخص کردیم:

use Illuminate\Validation\Rule;

Validator::make($data, [
    'email' => [
        'required',
        Rule::exists('staff')->where(function ($query) {
            $query->where('account_id', 1);
        }),
    ],
]);


file

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


filled

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


image

فیلدی که اعتبارسنجی می‌شود، باید یک تصویر با فرمت‌های (jpeg، png، bmp، gif، svg) باشد.


in:foo,bar,...

فیلدی که اعتبارسنجی می‌شود، باید در لیست داده‌های موجود قرار گیرد. از آنجا که این قاعده نیاز دارد که یک آرایه را implode کنید، متد Rule::in کمک می‌کند تا به سادگی این قانون را بسازید:

use Illuminate\Validation\Rule;

Validator::make($data, [
    'zones' => [
        'required',
        Rule::in(['first-zone', 'second-zone']),
    ],
]);


in_array:anotherfield

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


integer

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


ip

فیلدی که اعتبارسنجی می‌شود، باید یک آدرس IP باشد.


ipv4

فیلدی که اعتبارسنجی می‌شود، باید یک آدرس IPv4 باشد.


ipv6

فیلدی که اعتبارسنجی می‌شود، باید یک آدرس IPv6 باشد.


json

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


max:value

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


mimetypes:text/plain,...

فایلی که اعتبارسنجی می‌شود، باید با یکی از انواع MIME مشخص شده مطابقت داشته باشد:

'video' => 'mimetypes:video/avi,video/mpeg,video/quicktime'

برای تعیین نوع MIME فایل آپلود شده، محتویات فایل خوانده می‌شود و فریم ورک تلاش می‌کند تا نوع MIME را حدس بزند که ممکن است با نوع MIME ارائه شده توسط کلاینت متفاوت باشد.


mimes:foo,bar,...

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


Basic Usage Of MIME Rule

'photo' => 'mimes:jpeg,bmp,png'

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

لیست کامل انواع MIME و پسوند مربوط به آن‌ها را می‌توانید در لینک زیر مشاهده کنید:
https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types


min:value

فیلدی که اعتبارسنجی می‌شود، باید حداقل مقدار را داشته باشد. رشته‌ها، اعداد، آرایه‌ها، و فایل‌ها با همان روش قانون size ارزیابی می‌شوند.


nullable

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


not_in:foo,bar,...

فیلدی که اعتبارسنجی می‌شود، نباید در لیست داده‌های موجود قرار گیرد. از متد Rule::notIn می‌توان استفاده کرد و به سادگی این قانون را ایجاد کرد:

use Illuminate\Validation\Rule;

Validator::make($data, [
    'toppings' => [
        'required',
        Rule::notIn(['sprinkles', 'cherries']),
    ],
]);


numeric

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


present

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


regex:pattern

فیلدی که اعتبارسنجی می‌شود، باید با عبارات منظم (regular expression) داده شده مطابقت داشته باشد.

نکته: در هنگام استفاده از الگوریتم regex ، می‌توانید به جای استفاده از pipe delimiter، قوانین را در آرایه مشخص کنید، به خصوص اگر عبارات منظم شامل یک کاراکتر pipe باشند.


required

فیلدی که اعتبارسنجی می‌شود، باید در داده ورودی موجود باشد و خالی نیز نباشد. در صورتی یک فیلد empty یا خالی محسوب می‌شود که یکی از شرایط زیر را دارا باشد:

  • مقدار null است.
  • مقدار یک رشته خالی است.
  • مقدار یک آرایه خالی یا شئ Countable خالی است.
  • مقدار یک فایل آپلود شده بدون مسیر است.


required_if:anotherfield,value,...

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


required_unless:anotherfield,value,...

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


required_with:foo,bar,...

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


required_with_all:foo,bar,...

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


required_without:foo,bar,...

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


required_without_all:foo,bar,...

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


same:field

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


size:value

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


string

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


timezone

فیلدی که اعتبارسنجی می‌شود، باید یک شناسه منطقه زمانی معتبر براساس تابع پی اچ پی ‍ timezone_identifiers_list باشد.


unique:table,column,except,idColumn

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

مشخص کردن یک نام ستون سفارشی

'email' => 'unique:users,email_address'

مشخص کردن اتصال پایگاه داده (database connection) سفارشی

گاهی اوقات ممکن است نیاز باشد که یک connection سفارشی برای کوئری‌های پایگاه داده که توسط Validator ایجاد شده‌اند، تنظیم کنید. همانطور که در مثال بالا مشاهده کردید، تنظیم unique:users به عنوان یک قانون اعتبارسنجی از کانکشن پیش‌فرض پایگاه داده برای ایجاد کوئری از پایگاه داده استفاده می‌کند. به جای این کار می‌توان، کانکشن سفارشی و نام جدول را با استفاده از علامت «نقطه» مشخص کرد:

'email' => 'unique:connection.users,email_address'

وادار نمودن قانون Unique برای نادیده گرفتن یک ID مشخص

گاهی اوقات ممکن است بخواهید، یک ID مشخص را در طول بررسی قانون اعتبارسنجی unique نادیده بگیرید. برای مثال، یک صفحه «ویرایش مشخصات کاربر» را که شامل نام کاربر، آدرس ایمیل و مکان است را در نظر بگیرید. می‌خواهید مشخص کنید که فیلد آدرس ایمیل یکتا است. با این حال، اگر کاربر تنها فیلد نام را تغییر دهد و فیلد آدرس ایمیل تغییری نکند؛ در این صورت، به دلیل اینکه کاربر از قبل صاحب این آدرس ایمیل بوده است، ممکن است نخواهید یک خطای اعتبارسنجی صادر کنید.

برای نادیده گرفتن شناسه کاربر توسط این قانون اعتبارسنجی، می‌توانیم از کلاس Rule استفاده کنیم تا بتوانیم به سادگی این قانون را بسازیم. در این مثال، همچنین به جای مشخص کردن قوانین اعتبارسنجی با کاراکتر | می‌توانیم از یک آرایه برای ایجاد محدودیت در قوانین اعتبارسنجی استفاده ‌کنیم:

use Illuminate\Validation\Rule;

Validator::make($data, [
    'email' => [
        'required',
        Rule::unique('users')->ignore($user->id),
    ],
]);

اگر جدول از یک نام ستون به غیر از id برای کلید اصلی استفاده می‌کند، می‌توانید نام ستون را در هنگام فراخوانی متد ignore مشخص کنید:

'email' => Rule::unique('users')->ignore($user->id, 'user_id')

اضافه کردن بندهای اضافی با where

می‌توان با استفاده از متد where ، محدودیت‌های پرس و جوی اضافی را برای سفارشی سازی یک query ایجاد کرد. برای مثال، اجازه دهید یک محدودیت اضافه کنیم که account_id با مقدار 1 را مشخص می‌کند:

'email' => Rule::unique('users')->where(function ($query) {
    return $query->where('account_id', 1);
})


url

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


افزودن قوانین اعتبارسنجی به صورت شرطی


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

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

$v = Validator::make($data, [
    'email' => 'sometimes|required|email',
]);

در مثال بالا، فیلد email تنها در صورتی که در آرایه $data موجود باشد، اعتبارسنجی می‌شود.

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


اعتبارسنجی شرطی پیچیده

گاهی اوقات ممکن است بخواهید، منطق شرطی پیچیده‌تری را به قوانین اعتبارسنجی اضافه کنید. برای مثال، ممکن است به یک فیلد مشخص فقط در صورتی که فیلد دیگری دارای مقدار بیشتر از 100 باشد، نیاز داشته باشید. یا ممکن است تنها زمانی که فیلد دیگری موجود باشد، به دو فیلد با یک مقدار معین نیاز داشته باشید. افزودن این قوانین اعتبارسنجی در لاراول کار سختی نیست. ابتدا یک نمونه Validator با قوانین استاتیک که هرگز تغییر نمی‌کند، ایجاد کنید:


$v = Validator::make($data, [
    'email' => 'required|email',
    'games' => 'required|numeric',
]);

برای مثال فرض می‌کنیم، برنامه ما برای جمع آوری مجموعه بازی ساخته شده است. اگر یک جمع آوری کننده بازی در برنامه ثبت نام کرده و بیش از 100 بازی داشته باشد، از او می‌خواهیم توضیح دهد که چرا تعداد بازی‌های زیادی دارد. برای مثال، شاید فروشگاه مجازی بازی اجرا می‌کند یا شاید فقط از جمع آوری بازی لذت می‌برد. برای اضافه کردن این موارد به صورت شرطی، می‌توان از متد sometimes در نمونه Validator استفاده کرد.

$v->sometimes('reason', 'required|max:500', function ($input) {
    return $input->games >= 100;
});

آرگومان اولی که به متد sometimes منتقل می‌شود، نام فیلدی است که می‌خواهیم به صورت شرطی اعتبارسنجی کنیم. آرگومان دوم قوانین اعتبارسنجی است که قصد اضافه کردن آن‌ها را داریم. در صورتی که Closure به عنوان آرگومان سوم منتقل شده، مقدار true را برگرداند، این قوانین اضافه خواهند شد. این متد این امکان را می‌دهد که به سادگی بتوانیم اعتبارسنجی شرطی پیچیده را اعمال کنیم. حتی می‌توانید اعتبار‌سنجی شرطی را برای چند فیلد به صورت همزمان اضافه کنید:

$v->sometimes(['reason', 'cost'], 'required', function ($input) {
    return $input->games >= 100;
});
پارامتر $input ارسال شده به Closure نمونه‌ای از Illuminate\Support\Fluent است و می‌توان از آن برای دسترسی به ورودی و فایل‌ها نیز استفاده کرد.


اعتبارسنجی آرایه‌ها

اعتبارسنجی آرایه‌ها براساس فیلدهای ورودی نباید کار سختی باشد. می‌توان از علامت «نقطه» برای اعتبارسنجی صفات درون یک آرایه استفاده کرد. برای مثال، اگر درخواست HTTP ورودی دارای فیلد photos[profile] باشد، می‌توان آن را به صورت زیر اعتبارسنجی کرد:

$validator = Validator::make($request->all(), [
    'photos.profile' => 'required|image',
]);

همچنین می‌توان هر عنصری در درون آرایه را اعتبارسنجی کرد. برای مثال، برای اعتبارسنجی اینکه هر ایمیل در یک فیلد ورودی آرایه، منحصر به فرد است، می‌توان به صورت زیر عمل کرد:

$validator = Validator::make($request->all(), [
    'person.*.email' => 'email|unique:users',
    'person.*.first_name' => 'required_with:person.*.last_name',
]);

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

'custom' => [
    'person.*.email' => [
        'unique' => 'Each person must have a unique e-mail address',
    ]
],


ایجاد قوانین اعتبارسنجی سفارشی


استفاده از Rule Objects

لاراول انواع مختلفی از قوانین اعتبارسنجی را ارائه می‌دهد؛ با این حال ممکن است بخواهید برخی از قوانین را به صورت سفارشی ایجاد کنید. یک متد ثبت قوانین اعتبارسنجی سفارشی از اشیاء rule استفاده می‌کند. برای ایجاد یک شئ جدید rule، می‌توانید از دستور آرتیسان make:rule استفاده کنید. بیایید از این دستور برای تولید یک قانون یا rule استفاده کنیم، این قانون باید مشخص کند که یک رشته دارای حروف بزرگ است. لاراول rule جدید را در دایرکتوری app/Rules قرار می‌دهد:

php artisan make:rule Uppercase

هنگامی که قانون جدید ایجاد شد، می‌توانیم رفتار آن را نیز تعریف کنیم. یک شئ rule دارای دو متد است: passes و message . متد passes مقدار صفت و نام را دریافت می‌کند و بسته به اینکه آیا مقدار صفت معتبر است یا خیر، باید مقدار true یا false را بازگرداند. متد message پیام خطای اعتبارسنجی را که باید در هنگام ناموفق بودن اعتبارسنجی صادر شود، بازمی‌گرداند.

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class Uppercase implements Rule
{
    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        return strtoupper($value) === $value;
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'The :attribute must be uppercase.';
    }
}

اگر می‌خواهید یک پیام خطا را از فایل‌های translation خود بازگردانید، می‌توانید تابع کمکی trans را از متد message فراخوانی کنید:

/**
 * Get the validation error message.
 *
 * @return string
 */
public function message()
{
    return trans('validation.uppercase');
}

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

use App\Rules\Uppercase;

$request->validate([
    'name' => ['required', new Uppercase],
]);


استفاده از extension برای ثبت قوانین اعتبار‌سنجی سفارشی

روش دیگر برای ثبت قوانین اعتبار‌سنجی سفارشی، استفاده از متد extend در facade مربوط به Validator است. می‌توان از این روش در یک service provider استفاده کرد تا یک قانون اعتبارسنجی سفارشی را ثبت کرد:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Validator;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Validator::extend('foo', function ($attribute, $value, $parameters, $validator) {
            return $value == 'foo';
        });
    }

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

validator Closure سفارشی چهار آرگومان دریافت می‌کند:

نام $attribute که اعتبارسنجی می‌شود، $value مربوط به صفت، آرایه‌ای از $parameters ارسال شده به قانون اعتبارسنجی و یک نمونه Validator .

همچنین، می‌توان به جای انتقال یک Closure، یک کلاس و متد را به متد extend انتقال داد:

Validator::extend('foo', '[email protected]');


تعریف پیام خطا برای قوانین اعتبارسنجی سفارشی

همچنین، باید یک پیام خطا را برای قانون سفارشی خود تعریف کنید. این کار را می‌توان با استفاده از یک آرایه inline پیام سفارشی یا با اضافه کردن یک ورودی در فایل اعتبارسنجی language انجام داد. این پیام باید در سطح اول آرایه قرار گیرد، نباید این پیام‌ها را در آرایه custom که مختص پیام‌های خطای attribute است، قرار داد:

"foo" => "Your input was invalid!",

"accepted" => "The :attribute must be accepted.",

// The rest of the validation error messages...

هنگام ایجاد یک قانون اعتبارسنجی سفارشی، ممکن است نیاز به جایگزینی یک place-holder سفارشی برای پیام‌های خطا داشته باشید. می‌توانید با ایجاد یک Validator سفارشی همانطور که در مثال بالا توضیح داده شد، یک فراخوانی به متد replacer در facade مربوط به Validato r انجام دهید. می‌توان این کار را در متد boot یک service provider انجام داد:

/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    Validator::extend(...);

    Validator::replacer('foo', function ($message, $attribute, $rule, $parameters) {
        return str_replace(...);
    });
}


Implicit Extensions

در حالت پیش‌فرض، در هنگام اعتبارسنجی یک attribute که موجود نیست یا مقدار آن خالی است، همانطور که در قانون required تعریف شده است، قوانین اعتبارسنجی نرمال، مانند extension سفارشی، اجرا نمی‌شود. برای مثال، قانون unique در برابر یک مقدار null اجرا نمی‌شود:

$rules = ['name' => 'unique'];

$input = ['name' => null];

Validator::make($input, $rules)->passes(); // true

برای اجرای یک قانون، حتی زمانی که یک attribute خالی باشد، قانون یا rule باید اشاره کند که این attribute موردنیاز است. برای ایجاد این extension implicit می‌توانید از متد Validator::extendImplicit() استفاده کنید:

Validator::extendImplicit('foo', function ($attribute, $value, $parameters, $validator) {
    return $value == 'foo';
});
extension implicit تنها مشخص می‌کند که attribute موردنیاز است. اینکه آیا یک attribute ناموجود یا خالی نامعتبر است یا خیر، به خودتان بستگی دارد.

منابع مورد مطالعه جهت جمع آوری این مطلب:
https://laravel.com/docs/5.6/validation
https://www.lydaweb.com/article/courses/laravel-5-5-tutorial/262/اعتبارسنجی-در-لاراول-5-5


نظرات