تسلط بر لاراول مدرن: قابلیتهای پیشرفته، معماری تمیز، تست و کارایی خیرهکننده در Laravel 12+
لاراول در سالهای اخیر تحول چشمگیری داشته است. لاراول ۱۱ و ۱۲ اسکلتی سبکتر، bootstrapping صریح، بهبودهای قدرتمند در کوئریها، starter kitهای مدرن داخلی و ابزارهای پرکارایی first-party ارائه میکنند که به شما امکان میدهند اپلیکیشنهایی تمیزتر، قابلنگهداریتر و فوقالعاده سریع بنویسید. این راهنما سراغ تکنیکهای بسیار پیشرفته، مدرن و اغلب کمترشناختهشدهای میرود که هر توسعهدهندهٔ جدی لاراول باید در سال ۲۰۲۶ به آنها مسلط باشد.
قابلیتهایی از Laravel 12+ که همین حالا باید استفاده کنید
nestedWhere() – کوئریهای پیچیدهٔ تمیز بدون Closure (Laravel 12)
دیگر خبری از closureهای تودرتوی زشت برای شرطهای ترکیبی AND/OR نیست.
<?php
// Laravel 12+
$products = DB::table('products')
->where('status', 'active')
->nestedWhere('price', '<', 1000, 'or', 'discount', '>', 30)
->where('stock', '>', 0)
->get();
// Equivalent to the old messy version:
$products = DB::table('products')
->where('status', 'active')
->where(function ($query) {
$query->where('price', '<', 1000)
->orWhere('discount', '>', 30);
})
->where('stock', '>', 0)
->get();<Callout type="info"> nestedWhere() خوانایی منطق فیلترکردن در سناریوهای واقعی (بازهٔ قیمت + تخفیف + موجودی) را بهشکل چشمگیری بهتر میکند. هر چند تا که لازم دارید پشت هم زنجیره کنید. </Callout>
کلیدهای اصلی UUID / ULID (داخلی از Laravel 9، تکمیلشده در Laravel 11+)
در سیستمهای توزیعشده استفاده از IDهای auto-increment را کنار بگذارید.
<?php
use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Concerns\HasUlids;
class Order extends Model
{
use HasUuids; // or HasUlids for lexicographically sortable
// Optional: ordered UUIDs
public function newUniqueId(): string
{
return (string) Str::orderedUuid();
}
}<Note title="Pro Tip"> ULIDها برای دیتابیسهای shardشده و مرتبسازی مبتنی بر زمان عالیاند، بدون اینکه IDهای ترتیبی را افشا کنند. </Note>
مدلهای Prunable و MassPrunable – پاکسازی خودکار دیتابیس
<?php
use Illuminate\Database\Eloquent\Prunable;
use Illuminate\Database\Eloquent\MassPrunable;
use Illuminate\Database\Eloquent\Builder;
class TemporaryUpload extends Model
{
use MassPrunable; // faster, no events fired
public function prunable(): Builder
{
return static::where('created_at', '<=', now()->subDays(7));
}
}زمانبندیاش کنید:
// app/Console/Kernel.php or routes/console.php
Schedule::command('model:prune')->daily();اسکوپهای محلی مبتنی بر Attribute (Laravel 10.20+ / 11+)
<?php
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
class Post extends Model
{
#[Scope]
public function published(Builder $query): void
{
$query->where('published_at', '<=', now())
->where('is_draft', false);
}
}
// Usage
Post::published()->get();تکثیر مدل (جواهری کمترشناختهشده)
$order = Order::find(1);
$copy = $order->replicate(['total', 'paid_at']); // exclude sensitive fields
$copy->save();الگوهای معماری مدرن در Laravel 12+
Repository + Service Layer (همچنان پادشاهِ ۲۰۲۶)
<?php
// app/Repositories/OrderRepository.php
interface OrderRepositoryInterface
{
public function createWithItems(CreateOrderDTO $dto): Order;
}
// app/Services/OrderService.php
class OrderService
{
public function __construct(
private readonly OrderRepositoryInterface $repository,
private readonly InventoryService $inventory,
) {}
public function create(CreateOrderDTO $dto): Order
{
return DB::transaction(fn () => $this->repository->createWithItems($dto));
}
}آبجکتهای انتقال داده (DTO) با Constructor Property Promotion + Readonly
<?php
namespace App\Data;
readonly class CreateOrderDTO
{
public function __construct(
public readonly int $userId,
public readonly Collection $items, // collection of OrderItemDTO
public readonly ?string $notes = null,
) {}
public static function fromRequest(Request $request): self
{
return new self(
userId: $request->user()->id,
items: OrderItemDTO::collect($request->validated('items')),
notes: $request->validated('notes'),
);
}
}<Callout type="info"> برای قدرت باز هم بیشتر، آن را با پکیج laravel-data از Spatie ترکیب کنید (اعتبارسنجی، casting، صفحهبندی) – استاندارد de-facto در سال ۲۰۲۶. </Callout>
بهترین شیوههای تست – Pest در Laravel 11+ پیشفرض است
تستهای واحد با Pest (تمیز و گویا)
<?php
// tests/Unit/OrderServiceTest.php
it('creates order and decrements stock', function () {
$user = User::factory()->create();
$product = Product::factory()->create(['stock' => 10]);
$dto = new CreateOrderDTO(
userId: $user->id,
items: collect([new OrderItemDTO($product->id, 2)])
);
$order = app(OrderService::class)->create($dto);
expect($order)
->toBeInstanceOf(Order::class)
->and($product->fresh()->stock)->toBe(8);
});
it('throws when stock insufficient')->throws(InsufficientStockException::class, function () {
// ...
});تستهای Feature با RefreshDatabase
<?php
// tests/Feature/OrdersApiTest.php
it('allows authenticated user to create order', function () {
$user = User::factory()->create();
$product = Product::factory()->create(['stock' => 5]);
$response = $this->actingAs($user)
->postJson('/api/orders', [
'items' => [['product_id' => $product->id, 'quantity' => 2]],
]);
$response->assertCreated();
expect($product->fresh()->stock)->toBe(3);
});بهینهسازی کارایی – Octane همهچیز را عوض میکند
Laravel Octane (Swoole / RoadRunner / FrankenPHP)
composer require laravel/octane
php artisan octane:install
php artisan octane:start --server=frankenphp --watchتسکهای همزمان (موازیسازی واقعی)
use Laravel\Octane\Facades\Octane;
[$users, $products, $orders] = Octane::concurrently([
fn () => User::with('orders')->get(),
fn () => Product::where('featured', true)->get(),
fn () => Order::recent()->get(),
]);Cache و Tableهای Octane (درونحافظهای، مشترک بین Workerها)
// config/octane.php
'tables' => [
'leaderboard:5000' => ['user_id' => 'int', 'score' => 'int'],
],
// Usage
Octane::table('leaderboard')->set('user:123', ['user_id' => 123, 'score' => 9999]);
// Interval cache (auto-refreshes)
Cache::store('octane')->interval('daily-stats', fn () => calculateStats(), seconds: 86400);Tickها برای کارهای پسزمینه
Octane::tick('cleanup', fn () => TemporaryUpload::prune())
->seconds(60)
->immediate();<Callout type="info"> Octane + FrankenPHP استاندارد طلایی سال ۲۰۲۶ است – HTTP/3، HTTPS بدون نیاز به پیکربندی، و توان عملیاتی ۱۰ تا ۱۰۰ برابر در مقایسه با PHP-FPM سنتی. </Callout>
جمعبندی
لاراول مدرن (نسخههای ۱۰ تا ۱۲) دیگر «فقط یک فریمورک MVC» نیست؛ یک قدرت تمامعیار فولاستک است با bootstrapping صریح، قابلیت real-time رسمی (Reverb)، مسیریابی مبتنی بر صفحه (Folio)، کامپوننتهای تابعی (Volt) و کارایی در سطح production (Octane).
نکات کلیدی:
- از
nestedWhere()، UUID/ULID، مدلهای Prunable و اسکوپهای مبتنی بر attribute استفاده کنید - برای کدی قابلنگهداری، الگوی DTO + Service Layer + Repository را بپذیرید
- تستها را با Pest بنویسید – هم سریعتر است و هم لذتبخشتر
- برای production با Octane دیپلوی کنید (FrankenPHP پیشنهاد میشود)
- برای توسعهٔ سریع فولاستک از starter kitهای جدید همراه با Volt + Flux + shadcn/ui بهره بگیرید
از همین امروز ارتقا را شروع کنید. Laravel 12+ توسعهدهندهپسندترین نسخهٔ تا به امروز است – و دستاورد کارایی با Octane باعث میشود از خودتان بپرسید چطور تا حالا بدون آن سر میکردید.
این یادداشت ترجمهٔ فارسی نوشتهٔ خودم است — نسخهٔ اصلی (انگلیسی) در dev.to