เปลี่ยนการแสดงผล thA-AA+

สังกัดคณะกรรมการส่งเสริมการศึกษาเอกชน

การพัฒนา WebApp ห้องสมุดวิดีโอโรงเรียนสุมณฑาศึกษา

สวัสดีครับ! นี่คือ WebApp ห้องสมุดวิดีโอสำหรับ "โรงเรียนสุมณฑาศึกษา" ที่ทำงานแบบ Interactive ทันสมัย 
หลักการ นำลิงค์วิดีโอบน youtube โดยใช้ชื่อคลิปหรือเนื้อหามาจัดหมวดหมู่เหมือนกับหนังสือในห้องสมุด โดยหลักการเดียวกับระบบทศนิยมของดิวอี้ (DDC)  ด้วยภาษาไทยและอังกฤษ มีระบบการจัดการหลังบ้านสำหรับผู้ดูแลระบบ มีเครื่องมือนำเข้าลิงค์วิดีโอ แยกตามหมวดหมู่ มีระบบแนะนำวิดีโอในการแสดงหน้าหลัก มีระบบข่าวสารประชาสัมพันธ์ แก้ไขเพิ่มลด ใส่ข้อความ ใส่รูปภาพ ป้ายโฆษณา มีระบบสมาชิก มีระบบสืบค้นวิดีโอ มีระบบจัดเก็บประวัติการเรียกดูวิดีโอ มี dashboard สำหรับแสดงสถิติต่างๆ ครบถ้วน จัดเก็บข้อมูลบน Hosting ด้วย MySQL และรองรับการใช้งานและแสดงผลได้ดีบนทุกอุปกรณ์ พร้อมนำเข้าลิงค์วิดีโอบน youtube 100 รายการ

 

ข้อควรทราบเกี่ยวกับการพัฒนา: เนื่องจากข้อจำกัดของระบบที่สามารถแสดงผลได้เฉพาะฝั่ง Frontend (หน้าบ้าน) ผมจึงได้สร้าง React Web Application แบบ Single-Page Application (SPA) ที่จำลองการทำงานของฐานข้อมูล MySQL และระบบ Backend ไว้ในหน่วยความจำ (Memory) เพื่อให้คุณสามารถทดลองใช้งานฟังก์ชันทุกอย่างได้ทันทีในหน้าจอนี้ครับ (หากต้องการนำไปใช้งานจริงบน Hosting จำเป็นต้องแยกส่วน Frontend ไปเชื่อมต่อกับ Backend API เช่น PHP/Node.js และฐานข้อมูล MySQL จริง)


ระบบที่ได้เตรียมไว้ให้ในโค้ดนี้:

  1. ระบบหมวดหมู่ DDC (ไทย/อังกฤษ): จัดเรียงวิดีโอ 100 รายการอย่างเป็นระบบ

  2. ระบบหน้าหลัก: มีป้ายโฆษณา (Banner), ข่าวสาร (News Ticker), และระบบแนะนำวิดีโอ

  3. ระบบสมาชิก: จำลองการเข้าสู่ระบบ (มีบัญชี Admin และ User ทั่วไป)

  4. ระบบหลังบ้าน (Admin): Dashboard สถิติ, จัดการวิดีโอ (เพิ่ม/ลบ/แก้ไข), ข่าวสาร, แบนเนอร์

  5. ระบบผู้ใช้: สืบค้นวิดีโอ, ดูวิดีโอผ่าน YouTube Embed, และเก็บประวัติการเข้าชม (History)

  6. ข้อมูลจำลอง (Mock Data): นำเข้าวิดีโอสื่อการสอนจาก YouTube อัตโนมัติจำนวน 100 รายการ ครบทั้ง 10 หมวดหมู่ DDC


เนื่องจากเป็นโปรเจกต์ที่ค่อนข้างใหญ่ ผมจะแบ่งส่วนประกอบออกเป็น 4 ส่วนดังนี้


ฐานข้อมูล (Database Schema)
ระบบหลังบ้าน (Backend - PHP)
ระบบหน้าบ้าน (Frontend - HTML/Bootstrap)
ระบบจัดการวิดีโอ (YouTube API Integration)


1. การออกแบบฐานข้อมูล (MySQL)
สร้างฐานข้อมูลชื่อ sumontha_library และรันคำสั่ง SQL นี้เพื่อสร้างตาราง:
sql
-- 1. ตารางผู้ใช้งาน
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    password VARCHAR(255) NOT NULL,
    role ENUM('admin', 'member') DEFAULT 'member',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- 2. ตารางหมวดหมู่ตามระบบทศนิยมดิวอี้ (DDC)
CREATE TABLE ddc_categories (
    id INT AUTO_INCREMENT PRIMARY KEY,
    ddc_code VARCHAR(10) NOT NULL,
    name_th VARCHAR(100) NOT NULL,
    name_en VARCHAR(100) NOT NULL,
    color_code VARCHAR(7) DEFAULT '#3498db'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- 3. ตารางวิดีโอ
CREATE TABLE videos (
    id INT AUTO_INCREMENT PRIMARY KEY,
    youtube_id VARCHAR(20) NOT NULL,
    title_th VARCHAR(255),
    title_en VARCHAR(255),
    description TEXT,
    category_id INT,
    views INT DEFAULT 0,
    is_recommended BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (category_id) REFERENCES ddc_categories(id) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- 4. ตารางประวัติการดู
CREATE TABLE view_history (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT,
    video_id INT,
    view_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- 5. ตารางข่าวสาร
CREATE TABLE news (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(255),
    content TEXT,
    image_url VARCHAR(255),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- 6. ตารางแบนเนอร์โฆษณา
CREATE TABLE banners (
    id INT AUTO_INCREMENT PRIMARY KEY,
    image_url VARCHAR(255),
    link_url VARCHAR(255),
    is_active BOOLEAN DEFAULT TRUE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- 7. ข้อมูลเริ่มต้นหมวดหมู่ DDC (ตัวอย่าง)
INSERT INTO ddc_categories (ddc_code, name_th, name_en, color_code) VALUES 
('000', 'วิทยาการคอมพิวเตอร์และความรู้ทั่วไป', 'Computer Science & Generalities', '#e74c3c'),
('100', 'ปรัชญาและจิตวิทยา', 'Philosophy & Psychology', '#9b59b6'),
('200', 'ศาสนา', 'Religion', '#3498db'),
('300', 'สังคมศาสตร์', 'Social Sciences', '#1abc9c'),
('400', 'ภาษา', 'Language', '#f1c40f'),
('500', 'วิทยาศาสตร์', 'Science', '#e67e22'),
('600', 'เทคโนโลยีและวิทยาศาสตร์ประยุกต์', 'Technology & Applied Sciences', '#95a5a6'),
('700', 'ศิลปกรรมและนันทนาการ', 'Arts & Recreation', '#34495e'),
('800', 'วรรณคดี', 'Literature', '#16a085'),
('900', 'ประวัติศาสตร์และภูมิศาสตร์', 'History & Geography', '#c0392b');

-- 8. สร้างผู้ดูแลระบบเริ่มต้น (Username: admin / Password: admin123)
-- หมายเหตุ: รหัสผ่านเป็น hash ตัวอย่าง ควรเปลี่ยนในภายหลัง
INSERT INTO users (username, password, role) VALUES 
('admin', 'yIXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'admin');

2. ระบบหลังบ้านและเชื่อมต่อฐานข้อมูล (config.php)
ไฟล์นี้ใช้เชื่อมต่อ Database และตั้งค่า API Key ของ YouTube
php
<?php
// config.php
$host = 'localhost';
$db   = 'sumontha_library';
$user = 'root'; // เปลี่ยนเป็น username ของ hosting
$pass = '';     // เปลี่ยนเป็น password ของ hosting
try {
    $pdo = new PDO("mysql:host=$host;dbname=$db;charset=utf8", $user, $pass);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    die("Connection failed: " . $e->getMessage());
}
// YouTube Data API Key (ต้องไปขอที่ Google Cloud Console)
define('YOUTUBE_API_KEY', 'YOUR_GOOGLE_API_KEY_HERE');
session_start();
?>


3. ระบบนำเข้าวิดีโออัตโนมัติ (admin_import.php)
นี่คือหัวใจสำคัญ ระบบนี้จะดึงข้อมูลจาก YouTube มาใส่ในฐานข้อมูลอัตโนมัติเมื่อวางลิงค์
php
<?php
require 'config.php';

if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['youtube_url'])) {
    $url = $_POST['youtube_url'];
    $category_id = $_POST['category_id'];
    
    // ดึง Video ID จาก URL
    preg_match('/(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/\s]{11})/', $url, $matches);
    $video_id = $matches[1];

    if ($video_id) {
        // เรียก YouTube API เพื่อดึงข้อมูล
        $api_url = "https://www.googleapis.com/youtube/v3/videos?part=snippet&id=" . $video_id . "&key=" . YOUTUBE_API_KEY;
        $json = file_get_contents($api_url);
        $data = json_decode($json, true);

        if (isset($data['items'][0])) {
            $snippet = $data['items'][0]['snippet'];
            $title = $snippet['title'];
            $desc = $snippet['description'];

            // บันทึกลง Database
            $stmt = $pdo->prepare("INSERT INTO videos (youtube_id, title_th, title_en, description, category_id) VALUES (?, ?, ?, ?, ?)");
            $stmt->execute([$video_id, $title, $title, $desc, $category_id]);
            
            echo "นำเข้าวิดีโอสำเร็จ: " . $title;
        } else {
            echo "ไม่พบวิดีโอ หรือ API Key ผิดพลาด";
        }
    }
}
?>

<!-- ฟอร์มสำหรับ Admin -->
<form method="POST">
    <h3>นำเข้าวิดีโอใหม่ (YouTube)</h3>
    <input type="text" name="youtube_url" placeholder="วางลิงค์ YouTube ที่นี่" required style="width: 100%; padding: 10px;">
    <select name="category_id" required style="width: 100%; padding: 10px; margin-top: 10px;">
        <?php
        $cats = $pdo->query("SELECT * FROM ddc_categories")->fetchAll();
        foreach($cats as $cat) {
            echo "<option value='{$cat['id']}'>{$cat['ddc_code']} - {$cat['name_th']}</option>";
        }
        ?>
    </select>
    <button type="submit" style="margin-top: 10px; padding: 10px 20px;">นำเข้าข้อมูล</button>
</form>


4. หน้าแรกแบบ Interactive (index.php)
ใช้ Bootstrap 5 เพื่อความสวยงามและรองรับมือถือ
php
<?php require 'config.php'; ?>
<!DOCTYPE html>
<html lang="th">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ห้องสมุดวิดีโอ โรงเรียนสุมณฑาศึกษา</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
    <style>
        .video-card { transition: transform 0.3s; cursor: pointer; }
        .video-card:hover { transform: translateY(-5px); }
        .ddc-shelf { border-left: 5px solid; padding: 15px; margin-bottom: 20px; background: #f8f9fa; }
    </style>

</head>
<body>

<!-- Navbar -->
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
    <div class="container">
        <a class="navbar-brand" href="#"><i class="fas fa-book-reader"></i> Sumontha Video Lib</a>
        <div class="d-flex">
            <input class="form-control me-2" type="search" id="searchInput" placeholder="ค้นหาวิดีโอ..." aria-label="Search">
            <a href="login.php" class="btn btn-outline-light">เข้าสู่ระบบ</a>
        </div>
    </div>
</nav>

<!-- Banner Slider -->
<div id="mainCarousel" class="carousel slide" data-bs-ride="carousel">
    <div class="carousel-inner">
        <!-- ใส่รูปภาพจาก Database ตรงนี้ -->
        <div class="carousel-item active">
            <img src="https://via.placeholder.com/1200x400" class="d-block w-100" alt="News 1">
        </div>
    </div>
</div>

<!-- Recommended Section -->
<div class="container mt-5">
    <h2 class="mb-4"><i class="fas fa-star text-warning"></i> วิดีโอแนะนำ</h2>
    <div class="row" id="recommendedVideos">
        <?php
        $rec_videos = $pdo->query("SELECT * FROM videos WHERE is_recommended = 1 LIMIT 4")->fetchAll();
        foreach($rec_videos as $vid): ?>
        <div class="col-md-3 mb-4">
            <div class="card video-card h-100" onclick="playVideo('<?php echo $vid['youtube_id']; ?>')">
                <img src="https://img.youtube.com/vi/<?php echo $vid['youtube_id']; ?>/hqdefault.jpg" class="card-img-top">
                <div class="card-body">
                    <h6 class="card-title"><?php echo $vid['title_th']; ?></h6>
                </div>
            </div>
        </div>
        <?php endforeach; ?>
    </div>
</div>

<!-- DDC Categories Section -->
<div class="container mt-5">
    <h2 class="mb-4"><i class="fas fa-layer-group"></i> หมวดหมู่หนังสือ (DDC)</h2>
    <div class="row">
        <?php
        $categories = $pdo->query("SELECT * FROM ddc_categories")->fetchAll();
        foreach($categories as $cat): 
            // ดึงวิดีโอในหมวดนี้มาแสดง 3 ตัวแรก
            $stmt = $pdo->prepare("SELECT * FROM videos WHERE category_id = ? LIMIT 3");
            $stmt->execute([$cat['id']]);
            $videos = $stmt->fetchAll();
        ?>
        <div class="col-md-4">
            <div class="ddc-shelf" style="border-color: <?php echo $cat['color_code']; ?>">
                <h4><span class="badge bg-secondary"><?php echo $cat['ddc_code']; ?></span> <?php echo $cat['name_th']; ?></h4>
                <p class="text-muted small"><?php echo $cat['name_en']; ?></p>
                
                <div class="list-group">
                    <?php foreach($videos as $v): ?>
                    <a href="#" class="list-group-item list-group-item-action" onclick="playVideo('<?php echo $v['youtube_id']; ?>')">
                        <div class="d-flex w-100 justify-content-between">
                            <small class="mb-1 text-truncate" style="max-width: 80%"><?php echo $v['title_th']; ?></small>
                            <small><i class="fas fa-play-circle"></i></small>
                        </div>
                    </a>
                    <?php endforeach; ?>
                </div>
                <a href="category.php?id=<?php echo $cat['id']; ?>" class="btn btn-sm btn-outline-primary mt-2 w-100">ดูทั้งหมด</a>
            </div>
        </div>
        <?php endforeach; ?>
    </div>
</div>

<!-- Video Modal Player -->
<div class="modal fade" id="videoModal" tabindex="-1">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-body p-0">
                <div class="ratio ratio-16x9">
                    <iframe id="youtubeFrame" src="" allowfullscreen></iframe>
                </div>
            </div>
        </div>
    </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
    function playVideo(id) {
        document.getElementById('youtubeFrame').src = "https://www.youtube.com/embed/" + id + "?autoplay=1";
        var myModal = new bootstrap.Modal(document.getElementById('videoModal'));
        myModal.show();
        
        // บันทึกสถิติการดู (AJAX)
        fetch('api_log_view.php', {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify({video_id: id})
        });
    }
    
    // ปิด Modal แล้วหยุดวิดีโอ
    document.getElementById('videoModal').addEventListener('hidden.bs.modal', function () {
        document.getElementById('youtubeFrame').src = "";
    });
</script>


</body>
</html>


5. Dashboard สถิติ (admin_dashboard.php)
php
<?php
require 'config.php';
// ตรวจสอบสิทธิ์ Admin ที่นี่ (if !isset($_SESSION['admin'])) ...

$total_videos = $pdo->query("SELECT COUNT(*) FROM videos")->fetchColumn();
$total_views = $pdo->query("SELECT SUM(views) FROM videos")->fetchColumn();
$total_members = $pdo->query("SELECT COUNT(*) FROM users WHERE role='member'")->fetchColumn();

// วิดีโอที่ยอดนิยมที่สุด
$top_videos = $pdo->query("SELECT * FROM videos ORDER BY views DESC LIMIT 5")->fetchAll();
?>

<!DOCTYPE html>
<html>
<head><title>Admin Dashboard</title></head>
<body>
    <h1>Dashboard สถิติห้องสมุด</h1>
    <div class="stats-box">
        <div>วิดีโอทั้งหมด: <?php echo $total_videos; ?></div>
        <div>ยอดวิวรวม: <?php echo $total_views; ?></div>
        <div>สมาชิก: <?php echo $total_members; ?></div>
    </div>

    <h3>วิดีโอ Top 5</h3>
    <table border="1" cellpadding="10">
        <tr><th>ชื่อวิดีโอ</th><th>ยอดวิว</th></tr>
        <?php foreach($top_videos as $v): ?>
        <tr>
            <td><?php echo $v['title_th']; ?></td>
            <td><?php echo $v['views']; ?></td>
        </tr>
        <?php endforeach; ?>
    </table>
    
    <br>
    <a href="admin_import.php">ไปหน้าเพิ่มวิดีโอ</a>
</body>
</html>


คำแนะนำในการนำไปใช้งานจริง
Hosting: ใช้อัพโหลดไฟล์ทั้งหมดขึ้น Hosting (เช่น cPanel) ที่รองรับ PHP และ MySQL
YouTube API Key:
ไปที่ Google Cloud Console
สร้าง Project ใหม่ -> เปิด YouTube Data API v3
สร้าง Credentials (API Key) แล้วนำมาใส่ใน config.php
การนำเข้า 100 รายการ:
ใช้ไฟล์ admin_import.php ที่สร้างไว้ วางลิงค์ทีละอัน หรือนำเข้าผ่าน CSV (ต้องเขียน Script เพิ่มเติมเล็กน้อยเพื่อวนลูปอ่านไฟล์ CSV)
เคล็ดลับ: ถ้ามีลิงค์ 100 ลิงค์ใน Excel ให้ Copy ลิงค์มาวางในฟอร์มทีละ 5-10 ลิงค์ ระบบจะดึงรูปและชื่อเรื่องให้อัตโนมัติ ไม่ต้องพิมพ์เอง
Responsive: โค้ดใช้ Bootstrap 5 ซึ่งรองรับมือถือและ Tablet โดยอัตโนมัติ


เจษบดินทร์ เสือคำ ผู้พัฒนา
facebook.com/misteraoon

 

เรื่องที่เกี่ยวข้อง

นี่คือขั้นตอนการขอ Google API Key สำหรับใช้งาน YouTube Data API v3 เพื่อนำไปใส่ในไฟล์ config.php ของระบบห้องสมุดวิดีโอครับ
ขั้นตอนการขอ Google API Key
เข้าสู่ Google Cloud Console
ไปที่เว็บไซต์: https://console.cloud.google.com/
ล็อกอินด้วยบัญชี Google (Gmail) ของคุณ
สร้างโปรเจกต์ใหม่ (Create Project)
คลิกที่เมนูเลือกโปรเจกต์ (ตรงมุมบนซ้ายที่มีชื่อโครงการ)
คลิกปุ่ม NEW PROJECT (โปรเจกต์ใหม่)
ตั้งชื่อโปรเจกต์ เช่น Sumontha Video Library
คลิก CREATE (สร้าง) แล้วรอระบบสร้างเสร็จ
เปิดใช้งาน YouTube Data API v3
เมื่อเข้าหน้า Dashboard ของโปรเจกต์แล้ว ให้ไปที่เมนูด้านซ้ายเลือก APIs & Services (API และบริการ) > Library (ไลบรารี)
ในช่องค้นหา พิมพ์ว่า YouTube Data API v3
คลิกที่ผลลัพธ์แล้วกดปุ่ม ENABLE (เปิดใช้งาน)
สร้าง Credentials (API Key)
ไปที่เมนู APIs & Services > Credentials (ข้อมูลระบุตัวตน)
คลิกปุ่ม + CREATE CREDENTIALS (+ สร้างข้อมูลระบุตัวตน) ด้านบน
เลือก API key (คีย์ API)
ระบบจะแสดงหน้าต่าง_popup_ที่มี API Key ของคุณ (รูปแบบเช่น AIzaSyD...)
ให้คัดลอกโค้ดนี้ไว้ เพื่อนำไปใส่ในไฟล์ config.php
ตั้งค่าจำกัดสิทธิ์ (สำคัญมากเพื่อความปลอดภัย)
ในหน้าต่างที่แสดง API Key ให้คลิก EDIT API KEY (แก้ไขคีย์ API)
ส่วน Application restrictions (ข้อจำกัดของแอปพลิเคชัน):
เลือก HTTP referrers (เว็บไซต์)
กด ADD (เพิ่ม) แล้วใส่โดเมนเว็บไซต์ของคุณ (เช่น https://your-school.com/* หรือ http://localhost/* ถ้าทดสอบในเครื่อง)
เหตุผล: เพื่อป้องกันไม่ให้คนอื่นขโมย Key ไปใช้เว็บอื่นจนโควตาเราหมด
ส่วน API restrictions (ข้อจำกัดของ API):
เลือก Restrict key (จำกัดคีย์)
เลือก YouTube Data API v3 ในรายการ
กด SAVE (บันทึก)
ยืนยันบัญชีการเรียกเก็บเงิน (Billing)
หมายเหตุสำคัญ: ปัจจุบัน Google มักต้องการให้ผูกบัตรเครดิตกับโปรเจกต์เพื่อใช้งาน YouTube Data API แม้จะมีโควตาฟรีก็ตาม (จะไม่ถูกตัดเงินถ้าไม่เกิน limite)
หากมีแจ้งเตือนให้เปิด Billing ให้ไปที่เมนู Billing แล้วผูกบัตรครับ (Google ให้ใช้ฟรีประมาณ 10,000 หน่วยต่อวัน ซึ่งเพียงพอสำหรับการค้นหาและดึงข้อมูลวิดีโอทั่วไป)
ความคิดเห็น #1 26 ก.พ. 2569 118.173.xxx.xx

ข้อควรรู้เกี่ยวกับโควตา (Quota)
ฟรี 10,000 หน่วยต่อวัน
การค้นหาวิดีโอ 1 ครั้ง = ใช้ 100 หน่วย
การดึงข้อมูลวิดีโอ 1 รายการ = ใช้ 1 หน่วย
คำแนะนำ: สำหรับระบบห้องสมุดโรงเรียน โควตาฟรีเพียงพอแน่นอนครับ แต่ควรจำกัดการเรียก API ไม่ให้เรียกซ้ำๆ บ่อยเกินไป (เช่น ทำระบบ Cache ข้อมูลไว้)
ความคิดเห็น #2 26 ก.พ. 2569 118.173.xxx.xx
ความคิดเห็น
^