跳到主要内容

เนื้อหาภาษาไทย / 泰语内容

系统指南 内容已审核

การสร้าง 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 承接企业级 Web Application、API Integration 以及政府/企业管理系统的设计与开发,并提供长期支持。

查看软件开发服务