لاراول 6 منتشر شد! (آشنایی با ویژگی های جدید این نسخه)

18 شهریور 1398
لاراول 6 منتشر شد! (آشنایی با ویژگی های جدید این نسخه)

لاراول 6 منتشر شد!

چند ماهی بود که تیم توسعه ی لاراول در حال تست نسخه ی جدید (نسخه ی 6) بودند و بالاخره چند روز پیش (3 سپتامبر 2019) نسخه ی رسمی لاراول 6 برای استفاده ی عموم عرضه شد.

در تمامی نسخه های 5 لاراول (5.1 و 5.2 و ....) شاهد تغییرات بزرگی بودیم که از فریم ورک های نسبتا جوانی مانند لاراول انتظاری جز این هم نمی رود اما از این نسخه به بعد حس پایداری بیشتری خواهیم داشت چرا که پایه و زمینه ی لاراول محکم شده است و شما به عنوان توسعه دهنده نباید نگران بازنویسی کدها باشید. به خاطر همین پایداری و ثبات جدید تیم لاراول از روش semantic versioning برای تعیین ورژن های جدیدش استفاده خواهد کرد. بهتر است بدون توضیحات اضافی با قابلیت های جدید لاراول آشنا شویم.

Job middleware

از این به بعد به جای آنکه به صورت دستی کدهای boilerplate (پر استفاده و تکراری) خود را به job ها اضافه کنید، می توانید آن ها را به صورت یک middleware استخراج کرده و آن را به Job متصل کنید! فرض کنید می خواهیم قابلیت rate limiting (محدود کردن نرخ) به یک Job اضافه کنیم؛ تا قبل از نسخه ی 6 باید کدهای آن را به متد ()handle تک تک Job هایی اضافه می کردید که به نوعی به آن نیاز داشتند:

// app/Jobs/JobToBeThrottled.php
// Execute the job
public function handle() {
  // allow one job to process every 5 seconds
  Redis::throttle('key')->block(0)->allow(1)->every(5)->then(function () {
    // Handle the job
  }, function () {
    // Could not obtain lock
    return $this->release(5);
  });
}

اما در نسخه ی 6 می توانیم آن کد را از ()handle استخراج کرده و آن را به یک middleware مخصوص job منتقل کنیم؛ شما می توانید یک دیرکتوری در app/Jobs/Middleware یا مسیر دلخواه دیگری ایجاد کنید و فایل جدیدی برای middleware در آن پوشه بسازید:

// app/Jobs/Middleware/RateLimited.php
...
namespace App\Jobs\Middleware;
use Illuminate\Support\Facades\Redis;

class RateLimited {
  // Process the queued job.
  public function handle($job, $next) {
    Redis::throttle('key')
      ->block(0)->allow(1)->every(5)
      ->then(function () use ($job, $next) {
        // Lock obtained
        $next($job);
      }, function () use ($job) {
        // Could not obtain lock
        $job->release(5);
      });
  }
}

حالا می توانید این middleware را به job متصل کنید. Job هم قبل از پردازش شدن، کدهای آن را اجرا می کند. اگر با route middleware آشنا باشید، این فرآیند برایتان مشابه همان فرآیند خواهد بود:

// app/Jobs/JobToBeThrottled.php
use App\Jobs\Middleware\RateLimited;

// get the middleware that the job will use
public function middleware() {
  return [new RateLimited];
}

public function handle() {
  // handle the job
}

بدین ترتیب فایل های Job شما کوچک تر و خوانا تر می شوند. همچنین هر job روی کار مشخصی تمرکز می کند که باعث متمرکز شدن فایل های پروژه خواهد شد و از طرفی می توانید از یک middleware چندین بار استفاده کنید.

Lazy collection

لاراول 6 قابلیتی به نام Lazy collection را معرفی کرده است که به شما اجازه می دهد در هنگام کار با داده های سنگین استفاده از حافظه (memory usage) را کاهش دهید. اگر با eloquent model ها کار می کنید، می توانید به جای اینکه از ()all استفاده کرده و آن ها را یکجا وارد حافظه کنید، با استفاده از ()cursor آن ها را تک تک و نوبتی پردازش کنید.

به طور مثال کد زیر تمام مدل های eloquent را به صورت یکجا وارد حافظه می کند. حالا فرض کنید اگر هزاران پست در سایت خود داشته باشید چقدر حافظه را اشغال خواهید کرد:

// This loads all eloquent models into memory at the same time
// This may be a very large number if you have thousands of posts

$posts = App\Post::all()->filter(function ($post) {
    return $post->id > 500;
});

حالا به جای استفاده از ()all میتوانیم از ()cursor استفاده کنیم تا مدل ها تک تک وارد حافظه شوند:

$posts = App\Post::cursor()->filter(function ($post) {
  return $post->id > 500;
});

foreach ($posts as $post) {
  echo $post->id;
}

بهینه سازی Eloquent subquery ها

استفاده از Eloquent همیشه کار اجرای کوئری های پیچیده را آسان کرده است اما نسخه ی 6 لاراول اجرای subquery ها یا اجرای یک کوئری درون کوئری دیگر را از قبل هم آسان تر کرده است. این مسئله به طور خاص زمانی کاربردی است که بخواهیم داده هایی را از دو جدول مرتبط با هم بگیریم. در نسخه های 5 لاراول محدودیت هایی در زمینه ی استفاده از Subquery ها داشتیم و اکثر مواقع توسعه دهندگان بیخیال این قابلیت شده و کوئری های خود را با استفاده از ()DB::raw به هم متصل میکردند چرا که راحت تر بود.

در نسخه ی جدید متد addSelect به subquery ها اضافه شده است که قسمت بزرگی از مشکل را حل می کند. همچنین subquery های Eloquent از این به بعد به orderBy نیز دسترسی خواهند داشت.

برای مثال تصور کنید که دو جدول دارید: hotels (هتل ها) و reservations (رزرو شده ها). حالا فرض کنید می خواهیم بدانیم آخرین اتاق رزرو شده از یک هتل خاص از چه نوعی بوده است. به جای اینکه دو eloquent query جداگانه بنویسیم حالا می توانیم بگوییم:

use App\Reservation;
use App\Hotel;

return Hotel::addSelect(['last_booked_room' => Reservation::select('room_type')
  ->whereColumn('hotel_id', 'hotels.id')
  ->orderBy('created_at', 'desc')
  ->latest()
  ->limit(1)  
])->get();

پیام های سفارشی بهتر در احراز هویت

اگر از سیستم پیش فرض لاراول و gate ها برای احراز هویت کاربران استفاده می کنید باید بدانید که لاراول 6 متد جدیدی به نام Gate::inspect را معرفی کرده است. این متد نمایش پیام های سفارشی در طول فرآیند authorization را ساده تر میکند (به طور مثال اگر درخواست آن ها رد شد پیام خاصی برایشان نمایش داده شود).

فرض کنید متدی داشته باشید که بررسی میکند آیا فلان کاربر اجازه ی ویرایش پست ها را دارد یا خیر. قبل از ارائه ی نسخه ی 6 دریافت پیام خطا و نمایش آن به کاربر کار سختی بود اما با معرفی ()Gate::inspect میتوانید به راحتی پیام سفارشی خود را گرفته و به کاربر نمایش دهید. به طور مثال اگر بخواهید تنها کاربرانی که admin هستند بتوانند پست ها را ویرایش کنند احتمالا از یک gate با قابلیت ویرایش پست ها استفاده کرده اید:

// App/Providers/AuthServiceProvider.php
...

public function boot()
{
    $this->registerPolicies();

    // Define the gate that determines who can edit posts
    Gate::define('edit', function ($user) {
        return $user->isAdmin
          ? Response::allow()
          : Response::deny('You must be an administrator to edit posts.');
    });
}

در حالت عادی از متد های allows و denies استفاده می کنیم تا ببینیم آیا کاربر اجازه ی انجام کاری را دارد یا خیر؛ پاسخ آن نیز وابسته به متد Gate::define است. مشکل اینجاست که کد بالا پیام سفارشی You must be an administrator to edit posts را به کاربر نمی دهد بلکه فقط مقدار Boolean را برمی گرداند:

if (Gate::allows('edit')) {
  // let the user edit
}

if (Gate::denies('edit')) {
  // let the user edit
}

اما از این به بعد اگر بخواهید پیام خطای شخصی خود را ارسال کنید می توانید از Gate::inspect کمک بگیرید:

// get the full authorization response returned by the gate
$response = Gate::inspect('edit');

if ($response->allowed()) {
  // Let the user edit the post
} else {
  // Display the denial message
  // 'You must be an administrator to edit posts.'
  echo $response->message();
}

حذف پکیج Laravel UI

اتفاق جدید در لاراول 6 حذف پکیج laravel/ui است! البته این قابلیت به صورت کلی حذف نشده است بلکه دیگر به صورت پیش فرض هیچ scaffolding برای Bootstrap یا Vue وجود ندارد. اگر شما می خواهید از آن در پروژه هایتان استفاده کنید از دستور composer require laravel/ui استفاده کنید.

Laravel Vapor

بالاخره Laravel Vapor با تمام سر و صدایش منتشر شد! قبل از این آپدیت، اکثر افراد برای deploy کردن پروژه هایشان از Laravel Forge استفاده می کردند؛ با استفاده از Forge می توانید سرور مورد نظر خود را به پروژه متصل کنید و سپس forge آن را برای برنامه ی لاراول شما تنظیم می کند. مشکل اینجا بود که هنوز هم باید به صورت دستی آپدیت ها را انجام می دادید.

نمایی از Laravel Vapor
نمایی از Laravel Vapor

اما Vapor تمام این ها را به صورت خودکار انجام میدهد؛ Vapor به جای مدیریت و به روز رسانی سرورها برای برنامه ی شما، کاملا serverless (بدون سرور) است! البته منظور من این نیست که هیچ سروری وجود ندارد بلکه منظور این است که شما هیچ کاری با سرورها نخواهید داشت. نکته ی جالب دیگر این است که به جای پرداخت هزینه ها به صورت ثابت و ماهانه، تنها هزینه ی چیزی را می پردازید که از آن استفاده کنید. البته Vapor قابلیت های دیگری نیز دارد که با مراجعه به صفحه ی آن می توانید آن ها را مشاهده کنید.

بروزرسانی به نسخه ی 6

documentation رسمی لاراول اعلام کرده است که بروز رسانی از 5.8 به 6 حدود یک ساعت طول خواهد کشید و اگر از پکیج های خارجی و dependency های بیشتری استفاده می کنید این زمان طولانی تر هم خواهد شد.

برای بروزرسانی به فایل composer.json رفته و قسمت Laravel framework dependency را از *.5.8 به 6.0^ تغییر دهید:

// In composer.json
"laravel/framework": "^6.0",

سپس دستور زیر را در ترمینال اجرا کنید:

composer update

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

البته راه دیگر استفاده از Laravel Shift است که کار ها را به صورت خودکار برایتان انجام می دهد. راهنمای Laravel Shift را در این صفحه بخوانید.

آیا بروزرسانی کنیم؟

Laravel 6.0 نسخه ی جدید LTS (یا همان Long Term Support release) است که تا قبل از این متعلق به نسخه ی 5.5 بود. LTS یعنی حل باگ ها تا 2 سال و حل مشکلات امنیتی تا 3 سال تضمین شده است.

تاریخچه ی نسخه ی LTS و دیگر نسخه های برنامه

تاریخچه ی نسخه ی LTS و دیگر نسخه های برنامه

از آنجایی که پشتیبانی از رفع باگ ها به زودی برای نسخه ی 5.5 تمام می شود حتما به نسخه ی جدید بروزرسانی کنید.

نویسنده شوید
دیدگاه‌های شما (4 دیدگاه)

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

داداشی
11 آبان 1398
خیلی ممنون از اطلاعات مفید و بروزتون

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

ملیکا
24 مهر 1398
سپاسگذار زحمات شما هستیم. موید باشید

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

پاشا
22 شهریور 1398
دمت گرم اطلاعات خوبی بود مخصوصا اینکه همزمان با خود لاراول گذاشتی

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

امیر زوارمی
24 شهریور 1398
سلام دوست عزیز نظر لطف شماست.

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

سعید رضائیان
18 شهریور 1398
واقعا لذت میبرم وقتی میبینم که توی کشور خودمون هم محققینی داریم که اپدیت هستن و اینطوری به محض بروزرسانی ها اعلام میکنن! واقعا امیدوار تر شدم نسبت به ایران

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

امیر زوارمی
18 شهریور 1398
سلام دوست عزیز، نظر لطف شماست. تلاش ما در روکسو هم همینه که اطلاعات معتبر و به روز رو ارائه کنیم. خوشحالم که مورد رضایت شما بوده!

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