آموزش لاراول

راهنمای جامع آپگرید لاراول ۱۳ | تمام تغییرات و نکات

لاراول ۱۳ یکی از بزرگ‌ترین نسخه‌های اخیر فریمورک است که در Q1 2026 (مارس 2026) منتشر خواهد شد. این نسخه تغییرات ساختاری و امنیتی مهمی را با خود می‌آورد و نیاز به PHP 8.3 به…

1405/04/04 ۶ دقیقه مطالعه آخرین بروزرسانی: 1405/04/04

لاراول ۱۳ یکی از بزرگ‌ترین نسخه‌های اخیر فریمورک است که در Q1 2026 (مارس 2026) منتشر خواهد شد. این نسخه تغییرات ساختاری و امنیتی مهمی را با خود می‌آورد و نیاز به PHP 8.3 به عنوان حداقل نسخه دارد.

اگرچه زمان تخمینی آپگرید حدود ۱۰ تا ۳۰ دقیقه است، اما میزان پیچیدگی به طور مستقیم با حجم و پیچیدگی پروژه شما مرتبط است.

✨ چرا این آپگرید مهم است؟

  • بهبود‌های امنیتی: حفاظت CSRF و سریالایزیشن بهتر
  • ویژگی‌های جدید: PHP Attributes، Cache::touch() و موارد دیگر
  • بهینه‌سازی عملکرد: سرعت و کارایی بیشتر
  • Syntax و API جدید: کد تمیزتر و خوانایی بهتر

🎯 ویژگی‌های جدید لاراول ۱۳

🏷️ ۱. PHP Attributes Support (ویژگی‌های PHP)

لاراول ۱۳ از PHP 8 Attributes به عنوان جایگزینی برای property‌های کلاس برای پیکربندی اجزاء Laravel استفاده می‌کند. این یک تغییر غیرشکست‌پذیر است — پیکربندی مبتنی بر property‌های قدیمی همچنان کار می‌کند.

📚 Eloquent Models

اکنون می‌توانید از Attributes استفاده کنید تا نیازی به تعریف کردن $table، $hidden، $fillable و دیگر properties نباشد:

#[Table('users', key: 'user_id', keyType: 'string', incrementing: false)]
#[Hidden(['password'])]
#[Fillable(['name', 'email'])]
class User extends Model {}

Attributes دستیاب برای Models:

Attribute توضیح
#[Appends] ویژگی‌های بیشتری را append کنید
#[Connection] اتصال دیتابیس را تنظیم کنید
#[Fillable] فیلدهای قابل پُر‌کردن
#[Guarded] فیلدهای محافظت‌شده
#[Hidden] فیلدهای مخفی در خروجی
#[Table] نام جدول دیتابیس
#[Touches] رابطه‌های جدید شامل
#[Unguarded] تمام فیلدها قابل اختصاص هستند
#[Visible] فیلدهای نمایشی

📋 Queue Jobs

اکنون می‌توانید پیکربندی Queue را مستقیماً روی کلاس Job تعریف کنید:

#[Connection('redis')]
#[Queue('podcasts')]
#[Tries(3)]
#[Timeout(120)]
class ProcessPodcast implements ShouldQueue {}

Attributes دستیاب برای Queue:

#[Backoff]
#[Connection]
#[FailOnTimeout]
#[MaxExceptions]
#[Queue]
#[Timeout]
#[Tries]
#[UniqueFor]

این Attributes همچنین برای Listeners، Notifications، Mailables و Broadcast Events قابل استفاده هستند.

🖥️ Console Commands

Commands می‌توانند signature و description خود را با Attributes به جای class properties تعریف کنند:

#[Signature('mail:send {user} {--queue}')]
#[Description('Send a marketing email to a user')]
class SendMailCommand extends Command {}

🎁 اجزای دیگر

Attributes همچنین برای موارد زیر قابل دسترس هستند:

  • Form Requests: #[RedirectTo]، #[StopOnFirstFailure]
  • API Resources: #[Collects]، #[PreserveKeys]
  • Factories: #[UseModel]
  • Test Seeders: #[Seed]، #[Seeder]

⏱️ ۲. Cache::touch() – تمدید TTL بدون دریافت مقدار

PR #55954 یک متد Cache::touch() اضافه می‌کند که TTL یک آیتم کش‌شده را بدون دریافت یا بازذخیره کردن مقدار تمدید می‌کند:

// Extend by seconds
Cache::touch('user_session:123', 3600);
 
// Extend with a DateTime
Cache::touch('analytics_data', now()->addHours(6));
 
// Extend indefinitely
Cache::touch('report_cache', null);

چرا این مهم است؟ قبلاً، تمدید TTL نیاز به get و سپس put داشت، که نیاز به انتقال مقدار کش‌شده بر روی سیم داشت. Cache::touch() این مرحله را رد می‌کند:

  • Redis: یک فرمان EXPIRE استفاده می‌کند
  • Memcached: TOUCH استفاده می‌کند
  • Database: یک UPDATE صادر می‌کند

متد true در صورت موفقیت و false در صورتی که کلید موجود نباشد برمی‌گرداند.

✅ پشتیبانی: روش Cache::touch() در تمام drivers کش پیاده‌سازی شده است: Array، APC، Database، DynamoDB، File، Memcached، Memoized، Null، و Redis.

🐍 ۳. نسخه PHP مورد نیاز

لاراول ۱۳ نیاز به PHP 8.3 به عنوان حداقل نسخه دارد. این نمایندگی یک افزایش از نسخه ۱۲ (PHP 8.2) است.

نسخه Laravel نسخه PHP تاریخ انتشار رفع باگ تا پشتیبانی امنیتی تا
10 8.1 – 8.3 14 فوریه 2023 6 اگست 2024 4 فوریه 2025
11 8.2 – 8.4 12 مارس 2024 3 سپتامبر 2025 12 مارس 2026
12 8.2 – 8.5 24 فوریه 2025 13 اگست 2026 24 فوریه 2027
13 8.3 – 8.5 Q1 2026 (مارس) Q3 2027 Q1 2028

📦 بروزرسانی وابستگی‌ها

اولین و مهم‌ترین گام، بروزرسانی فایل composer.json است:

{
  "require": {
    "php": "^8.3",
    "laravel/framework": "^13.0",
    "laravel/tinker": "^3.0",
    "laravel/sanctum": "^4.0"
  },
  "require-dev": {
    "phpunit/phpunit": "^12.0",
    "laravel/pint": "^1.17",
    "laravel/sail": "^1.30"
  }
}

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

rm -rf vendor composer.lock
composer install
composer dump-autoload


🛡️ تغییرات Middleware و CSRF

تغییر نام VerifyCsrfToken

یکی از مهم‌ترین تغییرات در لاراول ۱۳:

❌ قدیمی

Illuminate\Foundation\Http\Middleware\VerifyCsrfToken

✅ جدید

Illuminate\Foundation\Http\Middleware\PreventRequestForgery

مراحل انتقال:

use Illuminate\Foundation\Http\Middleware\PreventRequestForgery;

->withoutMiddleware([PreventRequestForgery::class])


⚙️ تنظیمات کَش و Serialization

گزینه جدیدی به نام serializable_classes به کانفیگ کش اضافه شده که به طور پیش‌فرض false است. این کار جلوی حملات deserialization gadget chain را می‌گیره.

// config/cache.php
return [
    'serializable_classes' => [
        App\Models\User::class,
        App\Data\CachedDashboardStats::class,
    ],
];


🗄️ تغییرات Eloquent و دیتابیس

متد upsert() – اعتبارسنجی اجباری

حالا متد upsert حتماً نیاز به یک مقدار غیرتهی برای uniqueBy دارد.

User::upsert(
    [
        ['email' => 'john@example.com', 'name' => 'John'],
        ['email' => 'jane@example.com', 'name' => 'Jane'],
    ],
    'email',  // uniqueBy - اجباری
    ['name', 'updated_at']  // updateFields
);


🔄 Queue و Event‌های جدید

JobAttempted Event

خاصیت exceptionOccurred حذف و با $event->exception جایگزین شد.

use Illuminate\Queue\Events\JobAttempted;

Queue::listen(JobAttempted::class, function (JobAttempted $event) {
    if ($event->exception !== null) {
        Log::error('Job failed', ['exception' => $event->exception]);
    }
});

QueueBusy Event

خاصیت $connection به $connectionName تغییر نام داد.

use Illuminate\Queue\Events\QueueBusy;

class ListenerQueueBusy
{
    public function handle(QueueBusy $event)
    {
        Log::info("Queue busy: {$event->connectionName}");
    }
}


🌐 مسیریابی و Routing

تغییر الویت Route

الویت تطابق مسیرها عوض شده: مسیرهایی که دامنه (domain) مشخص دارند، اولویت بیشتری نسبت به مسیرهای بدون دامنه دارند.

// الویت 1 - Domain مشخص
Route::domain('api.example.com')->group(function () {
    Route::get('/users', 'UserController@index');
});

// الویت 2 - بدون Domain
Route::get('/users', 'UserController@index');


🧪 تغییرات Testing

String Factories – Reset بین تست‌ها

کارخانه‌های UUID و string دیگر بین تست‌ها ریست می‌شوند. اگر در تست‌های مختلف به persist شدن این فیکسچرها تکیه کرده بودید، باید در هر تست یا در متد setUp دوباره مقداردهی کنید.

public function setUp(): void
{
    parent::setUp();
    
    Str::createUuidsUsing(function () {
        return Str::uuid();
    });
}

Js::from() – Unicode Unescaping

حالا به طور پیش‌فرض از JSON_UNESCAPED_UNICODE استفاده می‌کند.


✅ بهترین روش‌های آپگرید

📋 چک‌لیست پیش آپگرید

  1. Backup دیتابیس و فایل‌های پروژه
    git commit -am "Pre-upgrade backup"
    mysqldump -u user -p database > backup.sql

  2. بررسی نسخه PHP (باید 8.3+ باشد)
    php -v

  3. اجرای تست‌های موجود
    php artisan test --stop-on-failure


🐛 Troubleshooting

❌ مشکل: “Class not found” برای PreventRequestForgery
✅ حل: از Illuminate\Foundation\Http\Middleware\PreventRequestForgery استفاده کنید
❌ مشکل: “Serializable classes not found”
✅ حل: کلاس‌های استفاده‌شده را به config/cache.php اضافه کنید
❌ مشکل: “upsert() requires uniqueBy parameter”
✅ حل: پارامتر uniqueBy را تنظیم کنید

🎯 نتیجه‌گیری

لاراول ۱۳ آپگرید سرمایه‌گذاری ارزشمندی برای امنیت و عملکرد است. ویژگی‌های جدید مثل PHP Attributes و Cache::touch() توسعه را آسان‌تر می‌کنند.

✅ توصیه‌های خلاصه:

  1. Backup بگیرید
  2. به‌ترتیب پیش بروید
  3. تست‌ها را اجرا کنید
  4. از ابزارهای خودکار استفاده کنید (Laravel Shift)
  5. Logs را نظارت کنید

برای اجرای این ایده در سایت خودت کمک می‌خواهی؟

اگر برای طراحی، توسعه یا بهینه‌سازی فنی سایت‌ات به مشاوره نیاز داری، از طریق فرم مشاوره با من در ارتباط باش.

نیاز به مشاوره داری؟

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