본문으로 건너뛰기

เนื้อหาภาษาไทย / 태국어 콘텐츠

시스템 가이드 검수 완료된 콘텐츠

การสร้าง Middleware ใน PHP

บทความนี้แนะนำแนวคิดเรื่อง Middleware ใน PHP ซึ่งเป็นส่วนประกอบที่ทำหน้าที่เป็นตัวกลางในการจัดการ Request และ Response ก่อนที่แอปพลิเคชันจะประมวลผล โดย Middlewa...

การสร้าง Middleware ใน PHP

ในบทก่อนหน้านี้ เราได้เรียนรู้เกี่ยวกับ Dependency Injection (DI) ซึ่งเป็นเทคนิคสำคัญในการสร้างแอปพลิเคชัน PHP ที่มีความยืดหยุ่นและทดสอบได้ง่าย ในบทนี้ เราจะมาเรียนรู้เกี่ยวกับอีกหนึ่งแนวคิดที่สำคัญไม่แพ้กัน นั่นคือ Middleware ซึ่งเป็นส่วนประกอบที่ช่วยจัดการกับ Request และ Response ก่อนที่แอปพลิเคชันของเราจะประมวลผล

What is Middleware?

Middleware เปรียบเสมือน "ท่อ" (pipe) หรือ "ตัวกรอง" (filter) ที่อยู่ระหว่าง Request ที่เข้ามายังแอปพลิเคชันของเรา และ Response ที่จะส่งออกไป Middleware สามารถใช้เพื่อ:

  • ตรวจสอบสิทธิ์การเข้าถึง (Authentication)
  • ตรวจสอบการอนุญาต (Authorization)
  • บันทึกข้อมูล (Logging)
  • ปรับเปลี่ยน Request หรือ Response
  • จัดการกับ Error
  • และอื่นๆ อีกมากมาย

แนวคิดของ Middleware ช่วยให้เราสามารถแยกส่วนของโค้ดที่เกี่ยวข้องกับการจัดการ Request และ Response ออกจากส่วนของโค้ดหลักของแอปพลิเคชัน ทำให้โค้ดของเรามีความสะอาด, เป็นระเบียบ และง่ายต่อการดูแลรักษา

เหตุผลเชิงออกแบบ: การใช้ Middleware ช่วยลดความซับซ้อนของ Controller หรือ Handler หลัก เพราะไม่ต้องใส่ logic ที่เกี่ยวข้องกับการจัดการ Request/Response ไว้ทั้งหมด ทำให้ Controller/Handler เน้นที่ Business Logic หลักได้เต็มที่ นอกจากนี้ยังช่วยให้ logic ที่เกี่ยวข้องกับการจัดการ Request/Response สามารถนำกลับมาใช้ใหม่ได้ง่ายในหลายๆ Route

Implementing Middleware

ในการสร้าง Middleware ใน PHP เรามักจะสร้าง Class ที่มี method หนึ่ง method ที่ทำหน้าที่เป็น "ตัวกลาง" ในการจัดการ Request และ Response ตัวอย่างเช่น:

<?php

namespace App\Middleware;

use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Server\RequestHandlerInterface as Handler;

class AuthenticationMiddleware
{
    public function __invoke(Request $request, Handler $handler): Response
    {
        // ตรวจสอบว่ามี User Login หรือยัง
        if (!isset($_SESSION['user_id'])) {
            // ถ้ายังไม่มี ให้ redirect ไปหน้า Login
            $response = new \Laminas\Diactoros\Response\RedirectResponse('/login');
            return $response;
        }

        // ถ้ามี User Login แล้ว ให้ส่งต่อไปยัง Handler ถัดไป
        $response = $handler->handle($request);
        return $response;
    }
}

ในตัวอย่างนี้ เราได้สร้าง Middleware ที่ชื่อ AuthenticationMiddleware ซึ่งทำหน้าที่ตรวจสอบว่ามี User Login หรือยัง ถ้ายังไม่มี User Login จะทำการ Redirect ไปยังหน้า Login ถ้ามี User Login แล้ว จะส่ง Request และ Response ไปยัง Handler ถัดไป

คำอธิบาย:

  • เราใช้ Interface Psr\Http\Message\ServerRequestInterface และ Psr\Http\Message\ResponseInterface เพื่อให้โค้ดของเราเป็นไปตามมาตรฐาน PSR-7 ซึ่งเป็นมาตรฐานสำหรับการจัดการ HTTP Message ใน PHP
  • Method __invoke เป็น Magic Method ที่จะถูกเรียกใช้เมื่อเราเรียก Class ในฐานะ Function
  • $handler->handle($request) เป็นการส่ง Request ไปยัง Handler ถัดไปใน Pipeline

แนวปฏิบัติที่ดี: ควรใช้ Interface สำหรับ Request และ Response เพื่อให้โค้ดมีความยืดหยุ่นและสามารถเปลี่ยน implementation ได้ง่ายในอนาคต

Middleware Pipeline

Middleware Pipeline คือการนำ Middleware หลายๆ ตัวมาเรียงต่อกัน เพื่อให้แต่ละ Middleware ทำงานตามลำดับที่กำหนดไว้ ตัวอย่างเช่น:

  1. AuthenticationMiddleware: ตรวจสอบสิทธิ์การเข้าถึง
  2. LoggingMiddleware: บันทึกข้อมูลการเข้าถึง
  3. ErrorHandlerMiddleware: จัดการกับ Error ที่เกิดขึ้น

ในการสร้าง Middleware Pipeline เราสามารถใช้ Library ต่างๆ ที่มีอยู่ เช่น middlewares/utils หรือ zend-stratigility ซึ่ง Library เหล่านี้จะช่วยให้เราสามารถสร้างและจัดการ Middleware Pipeline ได้อย่างง่ายดาย

ตัวอย่างการใช้ zend-stratigility:

<?php

use Laminas\Stratigility\MiddlewarePipe;
use Laminas\HttpHandlerRunner\Emitter\SapiEmitter;
use Laminas\Diactoros\ServerRequestFactory;
use App\Middleware\AuthenticationMiddleware;
use App\Middleware\LoggingMiddleware;
use App\Handler\HomepageHandler;

require 'vendor/autoload.php';

$pipeline = new MiddlewarePipe();

// เพิ่ม Middleware เข้าไปใน Pipeline
$pipeline->pipe(new LoggingMiddleware());
$pipeline->pipe(new AuthenticationMiddleware());

// เพิ่ม Handler หลัก
$pipeline->pipe(new HomepageHandler());

// สร้าง Request จาก Global Variables
$request = ServerRequestFactory::fromGlobals();

// Run Pipeline
$response = $pipeline->handle($request);

// ส่ง Response ออกไป
(new SapiEmitter())->emit($response);

คำอธิบาย:

  • เราสร้าง instance ของ MiddlewarePipe ซึ่งเป็น Class ที่ใช้สำหรับจัดการ Middleware Pipeline
  • เราใช้ method pipe() เพื่อเพิ่ม Middleware เข้าไปใน Pipeline ตามลำดับที่ต้องการ
  • HomepageHandler คือ Handler หลักที่จะประมวลผล Request เมื่อ Middleware ทั้งหมดทำงานเสร็จสิ้น
  • ServerRequestFactory::fromGlobals() สร้าง Request จาก Global Variables เช่น $_GET, $_POST, $_SERVER
  • SapiEmitter ส่ง Response กลับไปยัง Browser

ข้อดีของการใช้ Middleware Pipeline:

  • Separation of Concerns: แยก logic ที่เกี่ยวข้องกับการจัดการ Request/Response ออกจาก Business Logic หลัก
  • Reusability: สามารถนำ Middleware กลับมาใช้ใหม่ได้ในหลายๆ Route
  • Testability: สามารถทดสอบ Middleware แต่ละตัวได้อย่างอิสระ
  • Maintainability: โค้ดมีความสะอาด, เป็นระเบียบ และง่ายต่อการดูแลรักษา

Trade-offs: การใช้ Middleware อาจทำให้ Request มี Overhead เพิ่มขึ้นเล็กน้อยเนื่องจากต้องผ่านหลายขั้นตอน แต่โดยทั่วไปแล้วผลประโยชน์ที่ได้รับจะคุ้มค่ากว่า

สรุป: Middleware เป็นแนวคิดที่สำคัญในการสร้างแอปพลิเคชัน PHP ที่มีความยืดหยุ่น, ทดสอบได้ง่าย และง่ายต่อการดูแลรักษา โดยการใช้ Middleware Pipeline ช่วยให้เราสามารถจัดการกับ Request และ Response ได้อย่างมีประสิทธิภาพ

ในบทถัดไป เราจะเรียนรู้เกี่ยวกับการใช้ Queues และ Workers ใน PHP ซึ่งเป็นเทคนิคที่ช่วยให้เราสามารถประมวลผล Task ที่ใช้เวลานานได้อย่างมีประสิทธิภาพ

Office.in.th Custom Service

이 구조를 바탕으로 시스템을 개발하거나 맞춤 변경하고 싶으신가요?

Office.in.th는 엔터프라이즈 웹 애플리케이션, API 연동, 공공/민간 업무 관리 시스템을 설계·개발하며 장기 지원을 제공합니다.

소프트웨어 개발 서비스 보기