آشنایی با 10 ویژگی جدید در نسخه ی 5.8 لاراول

13 شهریور 1398
آشنایی با 10 ویژگی جدید در نسخه ی 5.8 لاراول

آشنایی با 10 ویژگی جدید در نسخه ی 5.8 لاراول

با سلام به شما همراهان گرامی روکسو. همانطور که می دانید لاراول یکی از محبوب ترین فریم ورک های حال حاضر دنیا برای زبان PHP است و به شما قابلیت های کم نظیری ارائه می دهد. نسخه ی 5.8 لاراول در اوایل سال 2019 ارائه شد و با قابلیت های جدیدی پا به میدان رقابت با دیگر فریم ورک های PHP گذاشته است. در مقاله ی قبلی ویژگی های جدید لاراول 5.7 را بررسی کردیم اما حالا نوبت به بررسی ویژگی های جدید و تغییرات لاراول 5.8 است.

Policy های جدید

Policy ها یکی از دو راه اصلی لاراول برای مدیریت احراز هویت کاربران هستند. در واقع آن ها کلاس هایی هستند که منطق احراز هویت و ارائه ی دسترسی به یک مدل یا منبع دیگر را مرتب می کنند. در نسخه های قبلی لاراول Policy ها باید به صورت AuthServiceProvider ثبت می شدند:

<?php

namespace AppProviders;

use AppPost;
use AppPoliciesTransactionPolicy;
use IlluminateSupportFacadesGate;
use IlluminateFoundationSupportProvidersAuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        Transaction::class => TransactionPolicy::class,
    ];

    /**
     * Register any application authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        //
    }
}

در مثال بالا Policy ما TransactionPolicy نام دارد و ما آن را وارد آرایه ی policies$ کرده ایم. اما با ارائه ی نسخه ی 5.8 لاراول دیگر نیازی به ثبت Policy ها به صورت دستی نیست. اگر مدل (model) و policy مربوط به آن بر اساس قرارداد های نام نویسی لاراول باشند و همچنین دیرکتوری policy در مکان پیش فرض خود باشد، لاراول به صورت خودکار policy ها را تشخیص می دهد و نیازی به ثبت دستی آن ها نیست.

اگر model ها یا policy های خود را در محلی غیر از محل پیش فرض تعیین شده توسط لاراول نگهداری می کنید، می توانید با استفاده از متد Gate::guessPolicyNamesUsing یک callback شخصی سازی شده را ثبت کنید. این متد معمولا از متد boot در AuthServiceProvider برنامه ی شما صدا زده می شود:

use IlluminateSupportFacadesGate;

Gate::guessPolicyNamesUsing(function ($modelClass) {
    // return policy class name...
});

پشتیبانی از Carbon 2.0

 Carbon پکیجی است که کلاس DateTime زبان PHP را extend کرده و کار با زمان و تاریخ را بسیار راحت می کند. Laravel 5.8 از نسخه ی 2.0 این پکیج پشتیبانی می کند که دو ویژگی جدید را به ما می دهد: کلاس CarbonImmutable و یک Date جدید.

برای شروع کار به دنبال فایل routesweb.php در محل نصب لاراول 5.8 بگردید و کد زیر را در آن وارد کنید:

use CarbonCarbon;

Route::get('carbon', function () {
    $date = Carbon::now();
    dump($date);
    $date->addDays(3);
    dump($date);
});

در مثال بالا یک route جدید ساخته ایم که تاریخ امروز را در متغیر date$ ذخیره کرده و آن را نشان می دهد. سپس 3 روز دیگر به تاریخ فعلی اضافه کرده و دوباره آن را نمایش می دهد. حالا اگر به مسیر یا همان route جدید (آدرس carbon/) بروید چنین چیزی می بینید:

خروجی تغییر تاریخ به صورت عادی
خروجی تغییر تاریخ به صورت عادی

همانطور که می بینید در اینجا شیء خود را تغییر داده ایم یعنی mutate شده است. برخی اوقات همین را هم می خواهیم اما در اکثر مواقع چنین چیزی اصلا به درد ما نمیخورد. تاریخ ها خصوصیات protected هستند بنابراین بهتر است که یک شیء کاملا جدید بسازیم و آن را نمایش دهیم نه اینکه شیء قبلی را ویرایش کنیم. اینجاست که CarbonImmutable به کار ما می آید. برای استفاده از این ویژگی به فایل AppServiceProvider بروید و کد زیر را وارد کنید:

// ...other includes
use IlluminateSupportDateFactory;
use CarbonCarbonImmutable;

class AppServiceProvider extends ServiceProvider
{
  public function register()
    {
        DateFactory::use(CarbonImmutable::class);
    }
}

حالا فایل routesweb.php را برای استفاده از Date جدید بروزرسانی کرده و از تاریخ یک کپی واقعی بسازید تا آن را تغییر دهیم:

use IlluminateSupportFacadesDate;

Route::get('carbon', function () {
    $date = Date::now();
    dump($date);
    $newDate = $date->copy()->addDays(7);
    dump($newDate);
});

حالا اگر مرورگر خود را refresh کنید چنین چیزی می بینید:

خروجی تغییر تاریخ به صورت immutable - تغییرات لاراول 5.8
خروجی تغییر تاریخ به صورت immutable

رابطه ی جدید HasOneThrough

لاراول 5.8 یک رابطه ی جدید به نام HasOneThrough را معرفی کرده است. با اینکه این ویژگی در لاراول جدید است اما از قبل در فریم ورک های دیگری مانند Rails وجود داشته است. فرض کنید سه مدل داشته باشیم: یک Supplier و یک Account و یک AccountHistory. به صورتی که Supplier یک Account داشته باشد و Account نیز یک AccountHistory داشته باشد.

در نسخه های قبلی برای پیدا کردن AccountHistory مربوط به یک supplier باید ابتدا خود supplier را پیدا میکردیم و سپس چنین چیزی می نوشتیم:

$supplier->account->accountHistory

اما حالا می توانید با استفاده از hasOneThrough و از طریق مدل account مستقیما به accountHistory دسترسی داشته باشید:

$history = $supplier->accountHistory

به طور مثال:

public function accountHistory()
{
    return $this->hasOneThrough(AccountHistory::class, Account::class);
}

پشتیبانی قوی تر از token hashing

یکی از نکات ریز لاراول که معمولا شناخته نمی شود این است که شما هنگام اجرای authentication (احراز هویت)، الزامی به استفاده از Laravel Passport ندارید بلکه یک token guard ساده وجود دارد که یک API ساده برای authentication به شما می دهد. حالا در لاراول 5.8 به شما اجازه داده شده است که ذخیره سازی token ها را به صورت هش های SHA-256 نیز انجام دهید تا آن ها به شکل متن ساده ذخیره نشوند و امنیت شما هم بالاتر برود.

Cache TTL دقیق تر

عملیات caching در نسخه های قبلی لاراول در حد دقیقه تنظیم می شد اما در نسخه ی 5.8 آن را به صورت ثانیه ای تعیین می کنید تا کنترل دقیقی روی مسائلی مثل زمان انقضاء در ذخیره ی آیتم ها و پیروی از استاندارد های PSR-16 داشته باشید. بنابراین هر زمان که به cache ارجاع داده می شود مطمئن شوید که ورودی ها را به صورت ثانیه تنظیم می کنید:

// Laravel 5.7 - این موارد تا 5 دقیقا ذخیره می شوند
Cache::put('foo', 'bar', 10);

// Laravel 5.8 - این موارد تا 5 ثانیه ذخیره می شوند
Cache::put('foo', 'bar', 10);

تنظیم timezone در یک schedule

در نسخه ی جدید لاراول می توانید timezone خود را برای یک scheduled task (عملیات هایی که با برنامه ی قبلی تنظیم شده و اجرا می شوند) تنظیم کنید. برای این کار به متد timezone نیاز خواهید داشت:

$schedule->command('run')
         ->daily()
         ->at('15:00')
         ->timezone('America/Chicago');

در نسخه های قبلی باید این کار را برای هر Task خود تکرار می کردید اما حالا می توانید متدی به نام scheduledTimezone در فایل app/Console/kernel.php تعریف کرده و timezone خود را return کنید. این timezone به هر scheduled task ای که داشته باشید متصل می شود:

/**
 * Get the timezone that should be used by default for scheduled events.
 *
 * @return DateTimeZone|string|null
 */
protected function scheduleTimezone()
{
    return 'America/Chicago';
}

بهبود Artisan call

همانطور که می دانید می توانید با استفاده از متد Artisan::call دستورات Artisan را از درون کدهایتان اجرا کنید. در نسخه های قبلی لاراول اگر می خواستید تنظیماتی را به دستور مورد نظرتان پاس دهید باید این کار را می کردید:

use IlluminateSupportFacadesArtisan;

Artisan::call('migrate:install', ['database' => 'foo']);

اما در لاراول 5.8 به جای پاس دادن تنظیمات به صورت آرایه می توانید آن ها را به صورت رشته پاس دهید:

Artisan::call('migrate:install --database=foo');

بهبود Artisan serve

یک راه ساده برای serve کردن برنامه های لاراول اجرای دستور php artisan serve است. در نسخه های قبلی لاراول، این دستور برنامه ی شما را در پورت پیش فرض 8000 اجرا میکرد بنابراین اگر یک برنامه ی دیگر را با همین دستور اجرا می کردید به خطا برمی خوردید (پورت اشغال شده بود). اما در نسخه ی جدید دستور server به دنبال پورت های خالی می گردد و تا پورت 8009 هم پیش می رود بنابراین می توانید با آن چندین برنامه را اجرا کنید.

متدهای کمکی برای Mock testing

این بروزرسانی نیز قصد تمیزتر کردن و خواناتر کردن کد های شما را دارد. فرض کنید می خواهیم یک سرویس transaction را mock کنیم و از آن بخواهیم که داده هایی را در رابطه با آن transaction برگرداند. در نسخه های قبلی باید می نوشتیم:

public function testBasicTest()
{       
  $service = Mockery::mock(TransactionService::class, function ($mock) {
        $mock->shouldReceive('find')->once()->with()->andReturn(['id' => 1, 'name' => 'foo']);
  });

  $this->instance(TransactionService::class, $service)
}

اما در نسخه ی 5.8 میتوانیم بنویسیم:

public function testBasicTest()
{
  $this->mock(TransactionService::class, function($mock){
    $mock->shouldReceive('find')->once()->with(1)->andReturn(['id' => 1, 'name' => 'foo'])
  });
}

بنابراین فراخوانی Mockery و bind کردن آن به container به صورت خودکار انجام می شود. همچنین دیگر نیازی به دستور زیر نداریم:

$this->instance

متد orWhere

در نسخه های قبلی اگر می خواستیم یک کوئری scop دار را با دستور or ترکیب کنیم، بدین صورت عمل می کردیم:

// scopeActive and scopeEmailVerified methods defined on the User model...
$users = AppUser::emailVerified()->orWhere(function (Builder $query) {
  $query->active();
})->get();

اما در نسخه ی 5.8 لاراول یک متد higher order به نام orWhere تعریف شده است بنابراین دیگر نیازی به نوشتن closure بالا نیست بلکه می توانیم به راحتی بگوییم:

$users = AppUser::emailVerified()->orWhere->active()->get();

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

برای توضیحات بیشتر به صفحات زیر از وب سایت رسمی لاراول مراجعه کنید:

نویسنده شوید
دیدگاه‌های شما

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