PHP Microservices Without Frameworks: สร้าง Microservices ด้วย Native PHP

โดย CyberMAN

ในยุคที่แอปพลิเคชันมีความซับซ้อนมากขึ้นเรื่อยๆ Microservices Architecture ได้กลายมาเป็นหนึ่งในแนวทางที่นักพัฒนาหลายคนเลือกใช้ บทความนี้จะพาไปทำความเข้าใจว่าเราสามารถสร้าง Microservices ด้วย PHP แบบ Native โดยไม่ต้องพึ่งพา Framework ขนาดใหญ่ได้อย่างไร

📌 บทความนี้เหมาะสำหรับ: นักพัฒนา PHP ที่ต้องการทำความเข้าใจแนวคิด Microservices และอยากลองนำไปใช้งานจริงโดยเริ่มจาก PHP พื้นฐาน

Microservices คืออะไร?

Microservices Architecture คือรูปแบบการออกแบบซอฟต์แวร์ที่แบ่งแอปพลิเคชันออกเป็น บริการขนาดเล็กหลายๆ ตัว แต่ละตัวทำงานอิสระและสื่อสารกันผ่านเครือข่าย ตรงกันข้ามกับ Monolithic Architecture ที่ใส่ทุกอย่างไว้ในโค้ดเบสเดียวกัน

คุณสมบัติMonolithicMicroservices
การ DeployDeploy ทั้งระบบพร้อมกันDeploy แยกอิสระแต่ละ Service
การ ScaleScale ทั้งระบบScale เฉพาะ Service ที่ต้องการ
เทคโนโลยีStack เดียวทั้งระบบแต่ละ Service เลือก Stack เองได้
ความซับซ้อนโค้ดซับซ้อนขึ้นเมื่อระบบใหญ่ซับซ้อนด้าน Infrastructure

หลักการออกแบบ Microservices ด้วย PHP

เมื่อออกแบบ Microservices ด้วย PHP Native มีหลักการสำคัญ 3 ข้อที่ควรคำนึงถึง:

1. Single Responsibility — หนึ่ง Service หนึ่งหน้าที่

แต่ละ Microservice ควรรับผิดชอบเพียง Domain เดียว เช่น:

  • UserService — จัดการข้อมูลผู้ใช้และการลงทะเบียน
  • AuthService — ดูแลการ Authentication และ Token
  • ProductService — จัดการแคตตาล็อกสินค้า
  • OrderService — ประมวลผลคำสั่งซื้อ

2. Independent Deployment — Deploy แยกกันได้

แต่ละ Service ควรมี Repository และสภาพแวดล้อมเป็นของตัวเอง สามารถอัปเดตหรือ Deploy ได้โดยไม่กระทบ Service อื่น

3. Network Communication — สื่อสารผ่านเครือข่าย

Services สื่อสารกันได้หลายรูปแบบ:

  • HTTP/REST API — ง่ายที่สุด เหมาะสำหรับเริ่มต้น
  • Message Queue (RabbitMQ, Redis) — เหมาะกับงาน Async
  • gRPC — ประสิทธิภาพสูง รองรับ Binary Protocol

โครงสร้างโปรเจกต์

ตัวอย่างโครงสร้างโฟลเดอร์สำหรับแต่ละ Microservice:

services/
├── user-service/
│   ├── src/
│   │   ├── Controllers/
│   │   ├── Models/
│   │   └── Services/
│   ├── public/
│   │   └── index.php
│   ├── composer.json
│   └── Dockerfile
├── auth-service/
│   ├── src/
│   ├── public/
│   └── Dockerfile
└── product-service/
    ├── src/
    ├── public/
    └── Dockerfile

ตัวอย่างโค้ด: HTTP Communication ใน PHP

วิธีง่ายที่สุดในการสื่อสารระหว่าง Services คือการใช้ file_get_contents() หรือ cURL:

แบบที่ 1: ใช้ file_get_contents

<?php
// ดึงข้อมูลผู้ใช้จาก UserService
$url = 'http://user-service.local/api/users/1';
$response = file_get_contents($url);
$user = json_decode($response, true);

echo "ชื่อผู้ใช้: " . $user['name'];

แบบที่ 2: ใช้ cURL (แนะนำ — ควบคุมได้มากกว่า)

<?php
function callService(string $url, string $method = 'GET', array $data = []): array
{
    $ch = curl_init($url);
    
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 10,
        CURLOPT_HTTPHEADER     => [
            'Content-Type: application/json',
            'Accept: application/json',
        ],
    ]);

    if ($method === 'POST') {
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
    }

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($response === false || $httpCode >= 400) {
        throw new RuntimeException("Service call failed: HTTP $httpCode");
    }

    return json_decode($response, true);
}

// ตัวอย่างการใช้งาน
try {
    // เรียก AuthService เพื่อ Login
    $authResult = callService(
        'http://auth-service.local/api/login',
        'POST',
        ['email' => 'user@example.com', 'password' => 'secret']
    );

    $token = $authResult['token'];
    echo "Login สำเร็จ! Token: $token";

    // เรียก UserService ดึงข้อมูล
    $user = callService('http://user-service.local/api/users/1');
    echo "ชื่อ: " . $user['name'];

} catch (RuntimeException $e) {
    echo "เกิดข้อผิดพลาด: " . $e->getMessage();
}

ตัวอย่าง: สร้าง Simple UserService

ตัวอย่าง UserService แบบ Native PHP ที่พร้อมใช้งาน:

<?php
// user-service/public/index.php

header('Content-Type: application/json');

$method = $_SERVER['REQUEST_METHOD'];
$path   = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

// Routing แบบ Simple
if ($method === 'GET' && preg_match('#^/api/users/(\d+)$#', $path, $m)) {
    echo json_encode(getUser((int)$m[1]));
} elseif ($method === 'GET' && $path === '/api/users') {
    echo json_encode(getAllUsers());
} elseif ($method === 'POST' && $path === '/api/users') {
    $body = json_decode(file_get_contents('php://input'), true);
    echo json_encode(createUser($body));
} else {
    http_response_code(404);
    echo json_encode(['error' => 'Not Found']);
}

// ฟังก์ชันจำลองฐานข้อมูล
function getUser(int $id): array
{
    $users = [
        1 => ['id' => 1, 'name' => 'สมชาย ใจดี',   'email' => 'somchai@example.com'],
        2 => ['id' => 2, 'name' => 'สมหญิง รักเรียน', 'email' => 'somying@example.com'],
    ];
    return $users[$id] ?? ['error' => 'User not found'];
}

function getAllUsers(): array
{
    return ['data' => [getUser(1), getUser(2)]];
}

function createUser(array $data): array
{
    // บันทึกลง DB จริงๆ ในโปรเจกต์จริง
    return ['success' => true, 'id' => rand(100, 999), 'data' => $data];
}

การใช้งาน Message Queue (Async)

สำหรับงานที่ไม่ต้องรอผลทันที เช่น ส่ง Email หรือประมวลผล Order แนะนำให้ใช้ Message Queue ร่วมกับ Redis หรือ RabbitMQ:

<?php
// Producer: OrderService ส่งข้อความไปยัง Queue
$redis = new Redis();
$redis->connect('redis', 6379);

$orderEvent = json_encode([
    'event'    => 'order.created',
    'order_id' => 1234,
    'user_id'  => 56,
    'total'    => 1500.00,
    'created_at' => date('c'),
]);

$redis->rPush('order_events', $orderEvent);
echo "Order event ส่งเข้า Queue เรียบร้อย";
<?php
// Consumer: EmailService รับข้อความจาก Queue (รัน background worker)
$redis = new Redis();
$redis->connect('redis', 6379);

echo "EmailService Worker เริ่มทำงาน...\n";

while (true) {
    $message = $redis->blPop(['order_events'], 5); // รอ 5 วิ
    
    if ($message) {
        $event = json_decode($message[1], true);
        
        if ($event['event'] === 'order.created') {
            sendOrderConfirmationEmail($event['user_id'], $event['order_id']);
            echo "ส่ง Email ยืนยัน Order #{$event['order_id']} แล้ว\n";
        }
    }
}

function sendOrderConfirmationEmail(int $userId, int $orderId): void
{
    // Logic ส่ง Email จริงๆ
    echo "Email ถึง User #$userId สำหรับ Order #$orderId\n";
}

Docker Compose สำหรับรัน Microservices

ใช้ Docker Compose จัดการ Services หลายตัวพร้อมกัน:

version: '3.8'

services:
  user-service:
    build: ./services/user-service
    ports:
      - "8001:80"
    environment:
      DB_HOST: user-db
      DB_NAME: users_db

  auth-service:
    build: ./services/auth-service
    ports:
      - "8002:80"
    environment:
      JWT_SECRET: your-secret-key

  product-service:
    build: ./services/product-service
    ports:
      - "8003:80"

  redis:
    image: redis:alpine
    ports:
      - "6379:6379"

  user-db:
    image: mysql:8
    environment:
      MYSQL_DATABASE: users_db
      MYSQL_ROOT_PASSWORD: secret
💡 เคล็ดลับ: ในโปรเจกต์จริง ควรเพิ่ม API Gateway ด้านหน้าเพื่อจัดการ Routing, Authentication, Rate Limiting และ Load Balancing ให้กับ Services ทั้งหมด แนะนำ Nginx หรือ Traefik

ข้อดีและข้อเสียของแนวทางนี้

✅ ข้อดี

  • ไม่มี Framework Overhead — เร็วและเบา
  • เข้าใจได้ง่าย เพราะเป็น PHP พื้นฐาน
  • แต่ละ Service สามารถใช้ PHP Version ต่างกันได้
  • Scale เฉพาะ Service ที่ Load สูงได้
  • Team แยกกันพัฒนาได้โดยไม่ Conflict

❌ ข้อเสีย

  • ต้องเขียน Boilerplate เยอะกว่า Framework
  • ซับซ้อนด้าน Infrastructure และ DevOps
  • Network Latency เพิ่มขึ้นจากการ Call ระหว่าง Services
  • Debugging ยากขึ้น ต้องการ Distributed Tracing

สรุป

การสร้าง Microservices ด้วย Native PHP เป็นไปได้อย่างสมบูรณ์แบบ โดยใช้เพียง cURL, JSON, และ HTTP Standards ที่มีอยู่แล้วใน PHP โดยไม่จำเป็นต้องพึ่งพา Framework ขนาดใหญ่ อย่างไรก็ตาม ควรพิจารณาให้ดีก่อนว่าโปรเจกต์ของคุณมีความซับซ้อนพอที่จะได้ประโยชน์จาก Microservices จริงหรือไม่ เพราะสำหรับโปรเจกต์ขนาดกลาง Monolithic ที่ออกแบบดีๆ ก็ยังเป็นทางเลือกที่ดี

#PHP#Microservices#WebDevelopment#Docker#BackendDevelopment#SoftwareArchitecture#NativePHP




PHP CI MANIA - PHP Code Generator 

โปรแกรมช่วยสร้างโค้ด "ลดเวลาการเขียนโปรแกรม"
ราคาสุดคุ้ม  
http://www.phpcodemania.com