Đăng ký và sử dụng Service

Tạo bởi Hoàng Vũ, chỉnh sửa cuối lúc 6 tháng 6, 2025

Trong bài này, bạn sẽ học cách đăng ký các service tùy chỉnh (như lớp gửi email, xử lý dữ liệu, v.v.) vào Container của Slim và sử dụng chúng trong route handler, controller hoặc middleware. Đây là một kỹ năng quan trọng để tổ chức ứng dụng theo hướng mô-đun và dễ mở rộng.

1 Cách bind class vào container

Bạn có thể đăng ký một class bất kỳ vào container để tái sử dụng trong nhiều nơi khác.

Cách 1: Bind bằng Closure

$container->set('mailer', function () {
    return new \App\Services\FakeMailer();
});

Cách 2: Bind bằng tên class (với PHP-DI)

use App\Services\FakeMailer;

$container->set(FakeMailer::class, function () {
    return new FakeMailer();
});

Với PHP-DI (trong Slim Skeleton), bạn cũng có thể dùng file container.php hoặc dependencies.php để cấu hình service.

2 Gọi service trong controller/route/middleware

Gọi trong route:

$app->get('/send', function ($request, $response, $args) use ($container) {
    $mailer = $container->get('mailer');
    $mailer->send("admin@example.com", "Hello từ Slim");
    $response->getBody()->write("Email đã được gửi giả lập.");
    return $response;
});

Gọi trong middleware:

$emailMiddleware = function ($request, $handler) use ($container) {
    $mailer = $container->get('mailer');
    $mailer->send("log@example.com", "Một request vừa được gửi tới " . $request->getUri());

    return $handler->handle($request);
};

Gắn middleware:

$app->get('/middleware-test', function ($request, $response) {
    $response->getBody()->write("Kiểm tra middleware gọi service!");
    return $response;
})->add($emailMiddleware);

3 Tạo một Service giả lập: FakeMailer

File: app/Services/FakeMailer.php

<?php

namespace App\Services;

class FakeMailer
{
    public function send($to, $message)
    {
        file_put_contents(__DIR__ . '/../../logs/email.log', "[" . date('Y-m-d H:i:s') . "] To: $to | Message: $message\n", FILE_APPEND);
    }
}

Ví dụ cụ thể

Bước 1: Tạo class FakeMailer

namespace App\Services;

class FakeMailer {
    public function send($to, $message) {
        file_put_contents(__DIR__ . '/../../logs/email.log', "[".date('Y-m-d H:i:s')."] To: $to | $message\n", FILE_APPEND);
    }
}

Bước 2: Đăng ký vào container

Trong container.php hoặc dependencies.php:

use App\Services\FakeMailer;

return [
    'mailer' => function () {
        return new FakeMailer();
    }
];

Bước 3: Sử dụng trong route

$app->get('/test-mail', function ($request, $response) use ($container) {
    $mailer = $container->get('mailer');
    $mailer->send('test@example.com', 'Đây là email gửi từ Slim');
    $response->getBody()->write("Email giả lập đã được gửi.");
    return $response;
});

Bước 4: Dùng trong middleware

$mailLogMiddleware = function ($request, $handler) use ($container) {
    $mailer = $container->get('mailer');
    $mailer->send("admin@example.com", "Có request: " . $request->getUri());

    return $handler->handle($request);
};

$app->get('/log-request', function ($request, $response) {
    $response->getBody()->write("Request đã được log qua email giả.");
    return $response;
})->add($mailLogMiddleware);

Kết luận

Service và Dependency Injection giúp tổ chức code sạch, linh hoạt và dễ kiểm soát hơn. Việc đăng ký các class như mailer, logger, validator... vào container là bước nền tảng để mở rộng hệ thống theo kiến trúc hiện đại.

Bài tập thực hành

  1. Tạo class FakeMailer có phương thức send($to, $message) và ghi log vào file.
  2. Đăng ký FakeMailer làm service trong container.
  3. Gọi service này trong route /test-mail.
  4. Gọi service từ middleware, ghi lại mỗi lần truy cập route /log-request.
Website Logo

Với hơn 10 năm kinh nghiệm lập trình web và từng làm việc với nhiều framework, ngôn ngữ như PHP, JavaScript, React, jQuery, CSS, HTML, CakePHP, Laravel..., tôi hy vọng những kiến thức được chia sẻ tại đây sẽ hữu ích và thiết thực cho các bạn.

Bình luận

Website Logo

Chào, tôi là Vũ. Đây là blog hướng dẫn lập trình của tôi.

Liên hệ công việc qua email dưới đây.

lhvuctu@gmail.com

Chúng Tôi Trên

Bạn đang muốn học về lập trình website?

Bạn cần nâng cao kiến thức chuyên nghiệp hơn để nâng cao cơ hội nghề nghiệp? Liên hệ