💾

Caching

Cache Strategies

<?php
use Illuminate\Support\Facades\Cache;

// Basic caching
$posts = Cache::remember('posts.all', 3600, function () {
    return Post::with('author')->latest()->get();
});

// Cache tags (Redis/Memcached only)
Cache::tags(['posts', 'home'])->put('featured', $featuredPosts, 3600);
Cache::tags(['posts'])->flush(); // Clear all posts cache

// Cache lock (prevent race conditions)
$lock = Cache::lock('processing-order-' . $orderId, 10);
if ($lock->get()) {
    try {
        // Process order...
    } finally {
        $lock->release();
    }
}

// Query caching với remember
$users = User::where('active', true)
    ->remember(60)  // Requires package
    ->get();
# Production cache commands
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan event:cache

# Clear all caches
php artisan optimize:clear
🔍

Query Optimization

Eager Loading (N+1 Problem)

<?php
// ❌ BAD: N+1 queries
$posts = Post::all();
foreach ($posts as $post) {
    echo $post->author->name; // Query mỗi lần loop
}

// ✅ GOOD: Eager loading (2 queries)
$posts = Post::with('author')->get();

// Nested eager loading
$posts = Post::with([
    'author',
    'comments.user',
    'tags'
])->get();

// Conditional eager loading
$posts = Post::with(['comments' => function ($query) {
    $query->where('approved', true)
          ->latest()
          ->limit(5);
}])->get();

// Lazy eager loading
$posts = Post::all();
$posts->load('author'); // Load sau khi đã có collection

Database Optimization

<?php
// Use select to limit columns
$users = User::select('id', 'name', 'email')->get();

// Chunk for large datasets
User::chunk(1000, function ($users) {
    foreach ($users as $user) {
        // Process...
    }
});

// Lazy collection (memory efficient)
User::lazy()->each(function ($user) {
    // Process one at a time
});

// Use DB façade for complex queries
DB::table('orders')
    ->selectRaw('DATE(created_at) as date, SUM(total) as revenue')
    ->groupBy('date')
    ->get();
🚀

Laravel Octane

Supercharge với Octane

composer require laravel/octane
php artisan octane:install

# Chạy với Swoole hoặc RoadRunner
php artisan octane:start --server=swoole --workers=4
<?php
// config/octane.php
'warm' => [
    // Warm services at startup
    App\Services\PaymentService::class,
    App\Services\InventoryService::class,
],

// Concurrent tasks
use Laravel\Octane\Facades\Octane;

[$users, $orders] = Octane::concurrently([
    fn () => User::count(),
    fn () => Order::sum('total'),
]);
⚠️ Lưu ý: Octane giữ app trong memory. Tránh static properties và đảm bảo services stateless.
← Bài 12: Testing Bài 14: Deployment →