لاراول 10 منتشر شده است و شامل بهروزرسانیها و امکانات جذاب بسیاری است که علاقهمندان لاراول را شگفتزده خواهد کرد. این نسخه نیز مانند نسخههای قبلی، ویژگیها و قابلیتهای جدیدی را معرفی کرده است. در این مقاله قصد داریم شما را با مهمترین بهروزرسانیها و امکانات جدید لاراول 10 آشنا کنیم. پس با ما همراه باشید.
قبلاً، لاراول در هر شش ماه یکبار نسخههای اصلی خود را منتشر میکرد، اما با لاراول ۹، تیم توسعهدهنده لاراول تمایل پیدا کرد که سالانه نسخههای جدید منتشر کند. با این وجود، تاریخ انتشار لاراول 10 در ۱۴ فوریه ۲۰۲۳ بود و این نسخه بهروزرسانیهای جدیدی را به همراه داشت.
لاراول 10 همانند سایر نسخههای جدید، دو سند رسمی را برای کمک به بهروزرسانی ارائه کرده است:
۱) راهنمای بهروزرسانی - این راهنما برای کاربرانی که قصد بهروزرسانی از لاراول ۹ یا نسخههای قدیمیتر را دارند، فراهم شده و یک راهنمای ساده و کوتاه برای آپدیت فراهم میکند.
دو تغییر مهم در این راهنما، بهروزرسانی وابستگیها و حداقل نیازمندیهای سیستمی است که الزام به PHP ۸.۱+ و Composer ۲.۲+ دارد. همچنین باید تنظیمات را برای "minimum-stability" بر روی "stable" قرار دهید. سایر تغییرات تأثیر متوسط، کم یا اختیاری دارند.
۲) یادداشتهای انتشار - این یادداشتها حاوی بهروزرسانیها و ویژگیهای جدید لاراول 10 نسبت به نسخههای قدیمیتر میباشد.
شما نمیتوانید لاراول 10 را با نسخههای PHP ۸.۰ یا قدیمیتر اجرا کنید. لاراول 10 تنها نسخههای PHP ۸.۱ و جدیدتر را پشتیبانی میکند، بنابراین با آخرین نسخه PHP ۸.۲ نیز سازگار است. همچنین اگر از لاراول ۹ استفاده میکنید، PHP ۸.۲ همچنان یک انتخاب مناسب برای پروژه شماست.
لاراول 10 ساختار برنامه و تمام کلاسهای مورد استفاده stubs را بهروزرسانی کرده تا انواع آرگومانها و مقادیر بازگشتی در تمام توابع مشخص شود. همچنین اطلاعات "DOC-TYPE" حذف شدهاند. به مثال زیر توجه کنید:
لاراول ۹:
/** * Get the path the user should be redirected to when they are not authenticated. * * @param \Illuminate\Http\Request $request * @return string|null */ protected function redirectTo($request) { if (! $request->expectsJson()) { return route('login'); } }
و در لاراول 10:
/** * Get the path the user should be redirected to when they are not authenticated. */ protected function redirectTo(Request $request): ?string { return $request->expectsJson() ? null : route('login'); }
با توجه به مثالهای ارائه شده، مشاهده میکنیم که در نسخه جدید، انواع پارامتر و مقدار بازگشتی به تمام متدها اضافه شدهاند. این کار باعث افزایش خوانایی، درک بهتر و جلوگیری از خطاها میشود. همچنین پیشنهاد میشود در نوشتن روشهای خودتان نیز از این ویژگیها استفاده کنید.
طراح لاراول (nunomaduro) با ارائه یک درخواست ادغام جامع، اعلام نوع پارامترها، مقادیر بازگشتی و توضیحات را در تمامی فایلها و مخازن مربوط به لاراول بهروزرسانی کرد که این کار بسیار ارزشمند و مهم تلقی میشود.
فاساد جدید Process به ما اجازه میدهد تا هر فرایند خارجی مانند فراخوانی اسکریپتهای خط فرمان را اجرا کنیم. همانطور که فاساد HTTP کار با APIها را آسانتر میکند، فاساد Process هم کار با تست و اجرای فرایندهای CLI را ساده خواهد کرد.
سادهترین روش استفاده از این ویژگی:
use Illuminate\Support\Facades\Process; $result = Process::run('ls -la'); $result->successful(); // اجرای موفقیت آمیز فرایند را بررسی میکند $result->failed(); // شکست فرایند را بررسی میکند $result->exitCode(); // خروجی کد فرایند را برمیگرداند $result->output(); // خروجی استاندارد فرایند را برمیگرداند $result->errorOutput(); // خروجی خطای فرایند را برمیگرداند $result->throw(); // اگر فرایند شکست خورده، استثنا میاندازد $result->throwIf(condition); // اگر شرط برقرار باشد و فرایند شکست خورده باشد، استثنا میاندازد
به عنوان مثال، میتوانیم دستور pwd را اجرا کنیم و دایرکتوری جاری را چاپ کنیم:
$result = Process::run('pwd'); return $result->output();
اگر خروجی را بررسی کنیم مسیر فعلی را میبینیم: /pathtoproject/projectname/public
اگر دستوری که وجود ندارد را اجرا کنیم:
$result = Process::run('ll'); return $result->errorOutput();
خطای زیر را مشاهده میکنیم: sh: ll: command not found
لایه Process شامل ویژگیهای زیادی از جمله:
اگر نیاز به اجرای فرایندهای طولانی مدت مانند npm run build داشته باشیم، میتوانیم آنها را پایش کنیم و وضعیت اجرا را بررسی نماییم.
همچنین روش fake() برای شبیهسازی فرایندها در تستها موجود است. به طور مثال اجرای دستور زیر چند ثانیه طول میکشد:
\Illuminate\Support\Facades\Process::run('npm run build')->output();
اما با کد زیر بلافاصله اجرا میشود:
\Illuminate\Support\Facades\Process::fake(); $this->info(\Illuminate\Support\Facades\Process::run('npm run build')->output());
به طور خلاصه، Facad جدید Process به ما این امکان را میدهد تا هر دستور CLI مورد نیاز را برنامهای از فایل PHP فراخوانی کنیم.
Laravel Pennant یک First Party Package است که توسط Tim McDonald از تیم اصلی لاراول نگهداری و توسعه داده میشود. این بسته چالش مدیریت feature flags در پروژههایی که بهطور مکرر بهروزرسانی میشوند را ساده میکند. این بسته یک راهکار ساده کاربردی شامل درایور آرایه حافظهای و دیتابیس ارائه میدهد.
برای شروع کافی است:
پس از اجرای Migration ها، جدول جدیدی به نام features به دیتابیس اضافه میشود. Pennant میتواند از آرایه حافظهای یا دیتابیس برای حل feature flags استفاده کند که پیشفرض دیتابیس است.
پرچم ویژگی یا Feature flags چیست؟ پرچمهای ویژگی لاراول یا Laravel Feature flags به تست سبکها، صفحات یا قابلیتهای جدید که فقط برای گروههای خاصی از کاربران مانند کارمندان یا مدیران قابل مشاهده است، کمک میکند. در واقع آنها امکان فعالسازی انتخابی قابلیتها در زمان اجرا بدون ایجاد تغییر در کد را فراهم میکنند.
برای تعریف یک ویژگی، از روش define روی فاساد Feature استفاده کنید. نام ویژگی و کلوژر مقدار اولیه را مشخص کنید. ویژگیها باید در یک سرویس پروایدر مثل AppServiceProvider
تعریف شوند:
public function boot(): void { Feature::define('new-dashboard-text, function () { return true; }); }
اینجا ما ویژگی جدید به نام “new-dashboard-text” را تعریف کردیم. اگر مقدار true را از کلوژر برگردانیم، به این معنی است که همه به این ویژگی دسترسی دارند. اگر نیاز باشد این ویژگی را فقط برای برخی افراد مثلا کارمندان و مدیران فعال کنیم، میتوانیم اینگونه تعریفش کنیم:
Feature::define('new-dashboard-text', fn (User $user) => $user->isAdmin() || $user->isEmployee());
در Blade میتوانیم از دیرکتیو @feature
برای مشخص کردن بخشی از کد که محدود به ویژگی است استفاده کنیم:
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg"> @feature('new-dashboard-text') <!-- 'new-style' is active --> <div class="p-6 text-gray-500"> {{ __("Welcome to the page!") }} </div> @else <!-- 'new-style' is inactive --> <div class="p-6 text-gray-900"> {{ __("You're logged in!") }} </div> @endfeature </div>
اگر با کاربر مدیر یا کارمند وارد شویم، "Welcome to the page!" را میبینیم و بقیه کاربران "You're logged in!" را مشاهده خواهند کرد. اما این چطور کار میکند؟ ابتدا باید به جدول features نگاهی بیندازیم که به این شکل است:
اینجا میبینیم کاربر با شناسه 1 که مدیر است، مقدار true
دارد. یعنی این کاربر به این ویژگی دسترسی دارد. کاربر دیگر با شناسه 2 که کارمند است هم به این ویژگی دسترسی دارد. اگر با کاربری که نه مدیر است و نه کارمند، وارد شوم، رکورد جدیدی به جدول اضافه میشود:
حال اگر کاربر 22 کارمند شد و نیاز به دسترسی به این ویژگی داشت، اما رکوردش در دیتابیس مقدار false
داشت، با ورود او بهروزرسانی نمیشد. به جای آن باید:
\Laravel\Pennant\Feature::activate('new-dashboard-text');
پس از بازدید مجدد از صفحه داشبورد، متن جدید نمایش داده میشود و رکورد دیتابیس هم بهروزرسانی میشود.
همچنین میتوانیم با شرط زیر بررسی کنیم آیا ویژگی برای کاربر جاری فعال است یا خیر:
if (Feature::active('new-dashboard-text')) { return to_route('dashboard'); }
خلاصه اینکه الان یک بسته خوب ساخته شده و تست شده با قابلیتهای عالی داریم. در ادامه به صورت خلاصه و تیتر وار ویژگی های لاراول Feature flags رو مینویسم:
دستور artisan test یک گزینهٔ جدید به نام profile دارد که به ما کمک میکند تستهای کندتر برنامه را پیدا کرده و آنها را بهبود دهیم.
برای مثال اگر داشته باشیم:
test('sleep for 3 seconds', function () { sleep(3); });
اگر php artisan test –profile
را اجرا کنیم، میتوانیم شناسایی کنیم کدام تستها زمان بیشتری برای اجرا گرفتهاند و به این ترتیب کندترینها را پیدا کنیم.
پس از انتشار لاراول 10، دستورات build-in نیازی به ورودی اولیه ندارند. وقتی این دستورات را بدون ورودی صدا میزنیم، برای استدلالهای مورد نیاز مانند زیر مورد سوال قرار میگیریم:
➜ php artisan make:model What should the model be named? ❯ Post Would you like any of the following? [none] none …… 0 all ……… 1 factory ………… 2 form requests …………… 3 migration ………… 4 policy …………… 5 resource controller …………… 6 seed ………… 7 ❯ 2,3,4 INFO Model [app/Models/Post.php] created successfully. INFO Factory [database/factories/PostFactory.php] was created successfully. INFO Migration [database/migrations/2023_03_27_151438_create_posts_table.php] was created successfully.
به این ترتیب دیگر نیازی به مشخص کردن تمام پارامترها در خط فرمان نیست و کاربر میتواند با راحتی گزینههای مورد نیاز را انتخاب کند.
روش Str::password
میتواند یک گذرواژه تصادفی و امن با طول مشخص تولید کند. این گذرواژه شامل ترکیبی از حروف، اعداد، نمادها و فاصله خواهد بود. به طور پیشفرض طول گذرواژه 32 کاراکتر است و شامل حروف، اعداد و نمادها میشود. میتوانیم دلخواه با یا بدون حروف، اعداد و نمادها تولید کنیم. ب
نحوه تعریف این متد به صورت زیر هست:
public static function password($length = 32, $letters = true, $numbers = true, $symbols = true, $spaces = false)
حال به این مثال توجه کنید:
> Str::password(10) = "L>e~8Ns9;!" > Str::password(letters: false) = "{/\\18{\]69~\_>:)%4//%61\\9-%.-{~%|&" > Str::password(numbers: false) = "OomXSZUnWA,jWTgise%>hcEsQnB,D.\\!"
به جای کلاس Str هم میتوانیم از تابع کمکی str() استفاده کنیم:
> str()->password() = "ZmJn^dib)GO)qutEER%QXmgt)fqJ\\PiC"
کاربردهای متعددی برای این روش وجود دارد مثل تولید گذرواژه موقت برای کاربر.
قبل از لاراول 10، اگر میخواستیم پروژه جدیدی با Laravel Breeze و Pest ایجاد کنیم، باید چند مرحله را طی میکردیم:
نصبکننده لاراول دو ویژگی کوچک مهم جدید دارد. هنگام ایجاد پروژه جدید لاراول با دستور «laravel new» میتوانیم از گزینه «–breeze» استفاده کنیم تا پروژهای با Laravel Breeze ایجاد شود.
همچنین اگر به جای phpunit از فریمورک تست Pest استفاده میکنیم، تغییر کوچک دیگری هم وجود دارد. دیگر نیاز نیست ابتدا «laravel new example-app» سپس «composer require pestphp/pest» را اجرا کنیم. بلکه میتوانیم از «laravel new example-app –pest» استفاده کنیم.
مثال نصب پروژه جدید با breeze و pest در یک دستور:
به منظور حذف نیاز به بسته DBAL (doctrine/dbal
) هنگام استفاده از change()
برای تغییر ستونها، ویژگی جدیدی در لاراول 10 معرفی شد که به توسعهدهندگان اجازه میدهد از روش change()
بدون نیاز به بستههای اضافه برای تغییر ستونها در MySQL، PostgreSQL و SQL Server استفاده کنند. این یک تغییر پرریسک بزرگ محسوب میشود، اما ارزش آن را دارد زیرا وابستگی به بسته اضافی دیگری را حذف میکند.
برای درک بهتر از این ویژگی جدید، مثال زیر را ببینید:
$table->integer('user_balance')->unsigned()->default(0)->comment('balance'); // `user_balance` is an integer, unsigned, defaults to '0', and column comment is 'balance'
برای درک بهتر، فرض کنید ستون user_balance
داریم و میخواهیم نوع آن را تغییر دهیم. از لاراول 10 به بعد میتوانیم ساده این کار را انجام دهیم:
$table->bigInteger('user_balance')->change(); // This will change `user_balance` to bigInteger instead of just integer
کد بالا نوع ستون را به bigInteger
تغییر میدهد. اما خاصیتهایی مانند UNSIGNED
، DEFAULT
و COMMENT
را حذف میکند. بنابراین باید هنگام تغییر نوع ستون، تمام خاصیتها را مجددا اضافه کنیم:
$table->bigInteger('user_balance')->unsigned()->default(0)->comment('balance')->change();
در صورت داشتن چند اتصال دیتابیس و نصب قبلی DBAL، توصیه میشود در تابع boot کلاس AppServiceProvider
از متدSchema::useNativeSchemaOperationsIfPossible()
استفاده کنید تا بتوانید از Native Column Modification Support بهره ببرید. برای انجام این کار به صورت زیر عمل کنید:
use IlluminateSupportFacadesSchema; class AppServiceProvider extends ServiceProvider { public function boot() { Schema::useNativeSchemaOperationsIfPossible(); } }
با استفاده از این روش میتوانید از Native Column Modification Support بهره ببرید. توجه داشته باشید برخی دیتابیسها مانند SQLite هنوز از این ویژگی پشتیبانی نمیکنند.
یکی دیگر از ویژگیهای قابل توجه لاراول 10، توانایی استفاده از روش Schema::getColumnType
بدون نیاز به بسته doctrine/dbal
است. در حال حاضر از Schema::getColumnType
به همراه DBAL برای دریافت نوع ستون استفاده میکنیم.
DBAL هر نوع ستون Native را به نوع معادل خودش در DBAL مپ میکند و بسیاری از انواع ستون مورد استفاده در لاراول در دیتابیسهای مختلف را پشتیبانی نمیکند.
اما در لاراول 10، روش جدید Schema::getColumnType
نوع ستون واقعی را برمیگرداند و نه معادل آن در DBAL. همچنین به شما اجازه میدهد تستهای یکپارچهسازی برای ویژگی جدید تغییر ستونهای Native بنویسید. میتوانید از این ویژگی برای دریافت نام نوع داده یا تعریف کامل نوع برای ستون مشخص استفاده کنید:
Schema::getColumnType('products', 'price'); // decimal
در حال حاضر استفاده از whereExists()
نیاز به پیکربندی کوئری تودرتو دارد. خوشبختانه در لاراول 10 امکان استفاده از یک بیلدر Eloquent به عنوان کوئری تودرتو وجود دارد. این امکان استفاده از متدهای سفارشی بیلدر، اسکوپهای مدل و غیره را فراهم میکند.
به عنوان مثال، در ورژن های قبلی اگر می خواستیم از whereExists()
استفاده کنیم باید اینگونه عمل می کردیم:
Order::whereExists(function ($query) { $query->from('products')->whereColumn('products.order_id', 'orders.id'); });
اما در لاراول 10 میتوانیم به این صورت عمل کنیم:
Order::whereExists( Product::whereColumn('products.order_id', 'orders.id') );
یکی از ویژگیهای جالب جدید لاراول 10، بهینهسازی Eager Loading زمانی است که کلیدی برای بارگذاری وجود ندارد. این تغییر بیشتر یک اصلاح است تا ویژگی، زیرا مشکل فعلی اجرای کوئریهای غیرممکن زیاد در Eager Loading روابط را برطرف میکند.
لاراول 10 ابتدا وجود کلید را بررسی میکند و اگر کلیدی وجود نداشته باشد، کالکشن خالی برمیگرداند و نیازی به کوئری غیرضروری به دیتابیس نیست.
select * from `table_name` where 0 = 1;
با این حال، بهروزرسانی جدید لاراول 10 ابتدا بررسی میکند که آیا اصلا کلیدی وجود دارد یا خیر، و اگر کلیدی وجود نداشته باشد، یک کالکشن خالی برمیگرداند. این کار نیاز به اجرای کوئریهای غیرضروری به دیتابیس را حذف میکند.
یک ویژگی بسیار عالی که چالش بزرگ کار با دیتابیسهای متعدد را برطرف میکند، تنها چهار روز قبل از انتشار لاراول 10 توسط تیم اصلی لاراول ادغام شد. در نسخههای قبلی، اگر با PostgreSQL و MySQL کار میکردیم و میخواستیم اولین مقدار یک لیست را به عنوان یک alias برگردانیم، باید کد خام دیتابیس مینوشتیم:
DB::table(‘visitors') ->when(isPostgreSQL(), fn ($query) => $query->select(DB::raw('coalesce(NULL, "user", "guest") AS "First Visitor"'))) ->when(isMySQL(), fn ($query) => $query->select(DB::raw('coalesce(NULL, `user`, `guest`) AS `First Visitor`')));
در بالا از تابع COALESCE برای برگرداندن اولین مقدار غیر خالی به عنوان alias استفاده کردیم. حالا میتوانیم کلاسهای قابل استفاده مجدد برای عبارات خام ایجاد کنیم تا نیاز به نوشتن مجدد کد خام دیتابیس نباشد. برای مثال بالا، ابتدا دو کلاس برای alias و تابع COALESCE ایجاد میکنیم:
class Alias implements Expression { // ... } class Coalesce implements Expression { // ... }
در بالا از تابع COALESCE()
برای برگرداندن اولین مقدار غیر خالی به عنوان یک alias به نام first visitor استفاده کردهایم. بنابراین هر بار نیاز به انجام عملیاتی مشابه داشته باشیم، باید دوباره کد خام دیتابیس بنویسیم.
ویژگی جدید امکان ایجاد کلاسهای قابل استفاده مجدد برای پیادهسازی عبارات و دستورات خام مورد نیاز در کوئریها را فراهم میکند. این کار نیاز به نوشتن مجدد کدهای خام دیتابیس را حذف میکند.
برای مثال بالا، ابتدا باید دو کلاس ایجاد کنیم:
class Alias implements Expression { // ... } class Coalesce implements Expression { // ... }
سپس میتوانیم بدون نیاز به کد خام، عملیات مورد نظر را انجام دهیم:
DB::table('visitors') ->select(new Alias(new Coalesce([NULL, 'user', 'guest']), 'First Visitor'));
این ویژگی امکانات زیادی را برای ارائه کلاسهای رایج عبارات خام توسط بستهها فراهم میکند و کدنویسی با دیتابیسهای چندگانه را سادهتر میکند.
حذف متدهای منسوخشده
متدهایی که در لاراول ۹ به عنوان منسوخشده علامتگذاری شده بودند، در لاراول 10 حذف شدهاند. اگر قصد بهروزرسانی یک پروژه فعلی به لاراول 10 را دارید، باید هر بخشی از کد که از متدهای منسوخشده استفاده میکند را با رویکرد جدیدی بازنویسی کنید تا همان نتیجه حاصل شود.
برخی از این موارد عبارتند از:
منابع: وب سایت kinsta.com و redberry.international
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.