Master PHP Framework & Tools

Dale LantoDale Lanto
4 min read

Let's break down these advanced Laravel topics one by one, with real-life examples and scenarios:

1. Event Handling in Laravel

Scenario: You're building an e-commerce application, and you want to send an email to users whenever they place an order, but you don’t want this to block the checkout process.

Example:

  • Create an event OrderPlaced.

  • Create a listener SendOrderConfirmationEmail.

// OrderPlaced.php (Event)
namespace App\Events;

use App\Models\Order;
use Illuminate\Queue\SerializesModels;
use Illuminate\Foundation\Events\Dispatchable;

class OrderPlaced
{
    use Dispatchable, SerializesModels;

    public $order;

    public function __construct(Order $order)
    {
        $this->order = $order;
    }
}

// SendOrderConfirmationEmail.php (Listener)
namespace App\Listeners;

use App\Events\OrderPlaced;
use Illuminate\Contracts\Queue\ShouldQueue;
use Mail;

class SendOrderConfirmationEmail implements ShouldQueue
{
    public function handle(OrderPlaced $event)
    {
        // Send email logic
        Mail::to($event->order->user->email)->send(new OrderConfirmation($event->order));
    }
}

You then dispatch the event when an order is placed:

// OrderController.php
use App\Events\OrderPlaced;

public function store(Request $request)
{
    // Order creation logic
    $order = Order::create($request->all());

    event(new OrderPlaced($order));
}

This helps decouple the event from the action of sending the email, keeping your code clean.


2. Queues in Laravel

Scenario: You want to send out a welcome email to users after they register, but you don't want the registration process to be slowed down by the email sending process.

Example:

  • Use Laravel queues to push the email sending task to the background.
  1. Setup Queue:

    In the .env file, set up a queue driver:

QUEUE_CONNECTION=database
  1. Job:
// WelcomeEmailJob.php
namespace App\Jobs;

use App\Mail\WelcomeEmail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Mail;

class WelcomeEmailJob implements ShouldQueue
{
    use Queueable;

    protected $user;

    public function __construct($user)
    {
        $this->user = $user;
    }

    public function handle()
    {
        Mail::to($this->user->email)->send(new WelcomeEmail($this->user));
    }
}
  1. Dispatch the Job:
// UserController.php
use App\Jobs\WelcomeEmailJob;

public function register(Request $request)
{
    $user = User::create($request->all());

    // Dispatch the job to queue
    WelcomeEmailJob::dispatch($user);
}
  1. Process the Queue: Run the queue worker to process jobs:
php artisan queue:work

3. Service Containers

Scenario: You want to inject your custom service classes into controllers or other parts of your application for handling complex business logic.

Example:

  • Create a custom payment service.
// PaymentService.php
namespace App\Services;

class PaymentService
{
    public function process($amount)
    {
        // Process payment logic
        return "Processing $amount payment.";
    }
}
  • Register the service in a service provider.
// AppServiceProvider.php
use App\Services\PaymentService;

public function register()
{
    $this->app->singleton(PaymentService::class, function ($app) {
        return new PaymentService();
    });
}
  • Inject and use it in the controller.
// OrderController.php
use App\Services\PaymentService;

public function checkout(PaymentService $paymentService)
{
    $result = $paymentService->process(100);
    return response()->json($result);
}

By using the service container, you follow the Dependency Injection pattern, making your application more testable and modular.


4. Middleware

Scenario: You want to restrict access to certain parts of your application based on specific conditions (e.g., a user must be an admin to access admin routes).

Example:

  • Create a custom middleware for admin check.
// AdminMiddleware.php
namespace App\Http\Middleware;

use Closure;

class AdminMiddleware
{
    public function handle($request, Closure $next)
    {
        if (auth()->user() && auth()->user()->isAdmin()) {
            return $next($request);
        }

        return redirect('/');
    }
}
  • Register it in Kernel.php:
protected $routeMiddleware = [
    'admin' => \App\Http\Middleware\AdminMiddleware::class,
];
  • Apply it to routes:
Route::middleware('admin')->group(function () {
    Route::get('/admin', [AdminController::class, 'index']);
});

5. Extending and Optimizing the Framework

Scenario: You want to extend Laravel to add custom functionality, like creating a custom artisan command or optimizing performance using caching.

Custom Artisan Command:

  1. Create Command:
php artisan make:command SendDailyReports
  1. Command Code:
// SendDailyReports.php
namespace App\Console\Commands;

use Illuminate\Console\Command;

class SendDailyReports extends Command
{
    protected $signature = 'report:daily';
    protected $description = 'Send daily reports to the admin';

    public function handle()
    {
        // Report generation logic
        $this->info('Daily reports sent.');
    }
}
  1. Schedule the command:
// Kernel.php
protected function schedule(Schedule $schedule)
{
    $schedule->command('report:daily')->daily();
}

Caching for Optimization:

  • Use cache for database-heavy logic, like retrieving popular posts.
// PostController.php
public function popularPosts()
{
    $popularPosts = Cache::remember('popular_posts', 60, function () {
        return Post::where('views', '>', 1000)->get();
    });

    return $popularPosts;
}

This helps reduce the load on the database, improving performance for frequently accessed data.


Summary:

  • Event Handling allows you to decouple actions like sending notifications.

  • Queues enable processing time-consuming tasks asynchronously.

  • Service Containers help manage class dependencies and improve testability.

  • Middleware allows flexible request filtering.

  • Extending the Framework provides the ability to add custom features and optimize performance, such as custom artisan commands and caching.

These features are essential when building complex, scalable, and efficient web applications.

0
Subscribe to my newsletter

Read articles from Dale Lanto directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Dale Lanto
Dale Lanto

A passionate Full Stack and Backend Web Developer with 7+ years of experience, specializing in PHP, Laravel, and a range of modern web technologies. I enjoy solving complex problems, optimizing systems, and delivering efficient, maintainable code. Check out some of my work at dalelanto.netlify.app or explore my GitHub at github.com/dalelantowork.