Kotchasan Framework Documentation

Kotchasan Framework Documentation

การจัดการ Input และ Request

TH 05 Feb 2026 06:23

การจัดการ Input และ Request

Kotchasan Framework มีระบบจัดการ Input และ Request ที่ครอบคลุมและทันสมัย รองรับ PSR-7 HTTP Message Interface พร้อมฟีเจอร์เพิ่มเติมสำหรับการพัฒนาเว็บแอปพลิเคชันที่ปลอดภัยและมีประสิทธิภาพ

สารบัญ

  1. Request Class - การจัดการ HTTP Request
  2. Input Class - การประมวลผลข้อมูล Input
  3. InputItem Class - การจัดการข้อมูลรายตัว
  4. Response Class - การสร้าง HTTP Response
  5. การจัดการพารามิเตอร์และการตรวจสอบ
  6. การอัปโหลดไฟล์
  7. การจัดรูปแบบการตอบกลับ
  8. ตัวอย่างการใช้งานในระบบจริง

Request Class - การจัดการ HTTP Request

การสร้าง Request Object

use Kotchasan\Http\Request;

// สร้าง Request จากตัวแปรระบบ
$request = new Request();

// สร้าง Request โดยไม่รวมข้อมูล superglobals
$request = new Request(false);

// ใช้ Request ในลักษณะ PSR-7
$newRequest = $request->withQueryParams(['page' => 2]);
$anotherRequest = $request->withParsedBody(['name' => 'John']);

การดึงข้อมูล HTTP Method และข้อมูลพื้นฐาน

// ตรวจสอบ HTTP Method
$method = $request->getMethod(); // GET, POST, PUT, DELETE, etc.

// Method Override Support (สำหรับ form ที่ไม่รองรับ PUT/DELETE)
// 1. ผ่าน header X-HTTP-Method-Override
// 2. ผ่าน parameter _method ใน POST

$isSecure = $request->isSecure(); // true หาก HTTPS
$protocol = $request->getProtocolVersion(); // 1.0, 1.1, 2.0
$uri = $request->getUri(); // URI object

// ตรวจสอบประเภท Request
$isAjax = $request->isAjax();
$isJson = $request->isJson();
$isGet = $request->isMethod('GET');
$isPost = $request->isMethod('POST');

การดึงข้อมูลพารามิเตอร์

// การดึงข้อมูล GET parameters
$id = $request->get('id'); // Returns InputItem
$page = $request->get('page', 1); // ค่าเริ่มต้น 1

// การดึงข้อมูล POST parameters
$name = $request->post('name');
$email = $request->post('email', '');

// การดึงข้อมูลแบบรวม (POST -> GET -> Cookie)
$value = $request->request('key', 'default_value');

// การดึงข้อมูล raw (ไม่ผ่าน wrapper)
$rawValue = $request->postRaw('data');
$rawGet = $request->getRaw('param');

// การดึงข้อมูล Server parameters
$userAgent = $request->server('HTTP_USER_AGENT');
$contentType = $request->server('CONTENT_TYPE');
$remoteAddr = $request->server('REMOTE_ADDR');

การจัดการ Headers

// ดึง Headers
$allHeaders = $request->getHeaders();
$contentType = $request->getHeaderLine('Content-Type');
$authorization = $request->getHeaderLine('Authorization');

// ตรวจสอบการมีอยู่ของ Header
if ($request->hasHeader('X-Requested-With')) {
    echo "This is an AJAX request";
}

// เพิ่ม/แก้ไข Headers (PSR-7 immutable)
$newRequest = $request->withHeader('Accept', 'application/json');
$requestWithHeaders = $request->withHeaders([
    'Accept' => 'application/json',
    'X-Custom-Header' => 'custom-value'
]);

การจัดการ Body และ JSON

// ดึง Request Body
$body = $request->getBody();
$bodyContent = $body->getContents();

// ดึงข้อมูล JSON
if ($request->isJson()) {
    $jsonData = $request->getJson();
    $specificValue = $request->getJsonData('user.name', 'Unknown');
}

// ดึงข้อมูล Parsed Body
$parsedBody = $request->getParsedBody(); // array หรือ object

// ตรวจสอบขนาด Content
$contentLength = $request->getContentLength();
if ($contentLength > 1024 * 1024) { // 1MB
    throw new Exception('Request too large');
}

Input Class - การประมวลผลข้อมูล Input

การใช้งาน Input Class

use Kotchasan\Input;

// สร้าง Input instance
$input = new Input($request);

// หรือใช้ static method
$input = Input::create($request);

// การใช้งานแบบ immutable (PSR-7)
$newInput = $input->withRequest($newRequest);
$inputWithQuery = $input->withQueryParams(['sort' => 'name']);
$inputWithBody = $input->withParsedBody(['action' => 'save']);

การดึงข้อมูลจากแหล่งต่างๆ

// ดึงข้อมูลจากแหล่งเฉพาะ
$postData = $input->get('username', '', 'post');
$getData = $input->get('page', 1, 'get');
$cookieData = $input->get('session_id', '', 'cookie');
$serverData = $input->get('HTTP_HOST', '', 'server');
$jsonData = $input->get('data', [], 'json');

// ดึงข้อมูลจากทุกแหล่ง (ลำดับ: POST -> GET -> JSON)
$value = $input->get('key', 'default'); // สำหรับ 'all' source

// ดึงข้อมูลทั้งหมดจากแหล่งเฉพาะ
$allPost = $input->all('post');
$allGet = $input->all('get');
$allCookies = $input->all('cookie');
$allServer = $input->all('server');
$allJson = $input->all('json');
$allData = $input->all(); // รวมทั้งหมด;

การใช้งานข้อมูลแบบ Type-safe

// การดึงข้อมูลพร้อมการแปลงประเภท
$userId = $input->getInt('user_id', 0);
$price = $input->getFloat('price', 0.0);
$isActive = $input->getBool('active', false);
$tags = $input->getArray('tags', []);
$description = $input->getString('description', '');

// การดึงข้อมูลประเภทพิเศษ
$email = $input->getEmail('email');
$url = $input->getUrl('website');
$phone = $input->getPhone('phone');
$date = $input->getDate('birth_date');
$time = $input->getTime('appointment_time');

// การดึงข้อมูล nested จาก JSON
$cityName = $input->getNestedValue('address.city', 'Unknown');
$coordinates = $input->getNestedArray('location.coordinates', []);

การตรวจสอบความปลอดภัย

// การทำความสะอาดข้อมูล
$cleanInput = $input->sanitize($userInput);
$cleanArray = $input->sanitizeArray($userArray);

// การตรวจสอบ CSRF Token
$token = $input->getString('csrf_token');
if (!$input->validateCsrfToken($token)) {
    throw new SecurityException('Invalid CSRF token');
}

// การสร้าง CSRF Token
$csrfToken = $input->generateCsrfToken();

// การตรวจสอบ Rate Limiting
if (!$input->checkRateLimit('login', 5, 300)) { // 5 attempts in 5 minutes
    throw new Exception('Too many attempts');
}

InputItem Class - การจัดการข้อมูลรายตัว

การใช้งาน InputItem

// InputItem จะถูกสร้างโดยอัตโนมัติเมื่อใช้ get() methods
$username = $request->get('username'); // Returns InputItem

// การแปลงประเภทข้อมูล
$asString = $username->toString();
$asInt = $username->toInt();
$asFloat = $username->toFloat();
$asBool = $username->toBool();
$asArray = $username->toArray();

// การตรวจสอบและทำความสะอาด
$filtered = $username->filter(); // กรองข้อมูลอันตราย
$alphanumeric = $username->alphanumeric(); // เฉพาะตัวอักษรและตัวเลข
$oneLine = $username->oneLine(); // ลบ newline และ tab
$truncated = $username->cut(50); // ตัดให้เหลือ 50 ตัวอักษร

// การตรวจสอบรูปแบบ
$cleanEmail = $username->email(); // ตรวจสอบรูปแบบ email
$cleanUrl = $username->url(); // ตรวจสอบรูปแบบ URL
$cleanPhone = $username->phone(); // ตรวจสอบรูปแบบเบอร์โทร
$cleanDate = $username->date(); // ตรวจสอบรูปแบบวันที่

// การประมวลผลข้อความ
$topic = $username->topic(); // สำหรับหัวข้อ
$detail = $username->detail(); // สำหรับรายละเอียด
$description = $username->description(); // สำหรับคำอธิบาย
$keywords = $username->keywords(); // สำหรับคีย์เวิร์ด
$textarea = $username->textarea(); // สำหรับ textarea

// การตรวจสอบการมีอยู่
$exists = $username->exists(); // ตรวจสอบว่ามีค่าหรือไม่
$isEmpty = $username->isEmpty(); // ตรวจสอบว่าว่างหรือไม่;

การใช้งานแบบ Fluent Interface

// Chain methods สำหรับการประมวลผลข้อมูล
$processedValue = $request->get('user_input')
    ->filter()           // กรองข้อมูลอันตราย
    ->oneLine()          // ลบ newline
    ->cut(100)           // ตัดเหลือ 100 ตัวอักษร
    ->toString();        // แปลงเป็น string

$cleanNumber = $request->get('amount')
    ->number()           // ตรวจสอบว่าเป็นตัวเลข
    ->toFloat();         // แปลงเป็น float

$validatedData = $request->get('data')
    ->json()             // ตรวจสอบ JSON format
    ->toArray();         // แปลงเป็น array;

Response Class - การสร้าง HTTP Response

การสร้าง Response พื้นฐาน

use Kotchasan\Http\Response;

// สร้าง Response ใหม่
$response = new Response();

// ตั้งค่า Status Code
$response = $response->withStatus(200); // OK
$response = $response->withStatus(404, 'Not Found');
$response = $response->withStatus(500, 'Internal Server Error');

// การตั้งค่า Headers
$response = $response->withHeader('Content-Type', 'application/json');
$response = $response->withHeaders([
    'Cache-Control' => 'no-cache',
    'X-Frame-Options' => 'DENY'
]);

// การตั้งค่า Content
$response = $response->withContent('Hello World');
$content = $response->getContent();

การสร้าง JSON Response

// JSON Response พื้นฐาน
$data = ['message' => 'Success', 'data' => $userData];
$jsonResponse = $response->json($data, 200);

// Static methods สำหรับ JSON
$successResponse = Response::makeJson(['success' => true], 200);
$errorResponse = Response::makeJson(['error' => 'Not found'], 404);

// Predefined JSON responses
$okResponse = Response::makeOk(['data' => $data]);
$createdResponse = Response::makeCreated(['id' => $newId]);
$badRequestResponse = Response::makeBadRequest(['error' => 'Invalid input']);
$unauthorizedResponse = Response::makeUnauthorized(['error' => 'Login required']);
$forbiddenResponse = Response::makeForbidden(['error' => 'Access denied']);
$notFoundResponse = Response::makeNotFound(['error' => 'Resource not found']);
$serverErrorResponse = Response::makeServerError(['error' => 'Internal error']);

การสร้าง HTML Response

// HTML Response
$htmlContent = '<html><body><h1>Welcome</h1></body></html>';
$htmlResponse = $response->html($htmlContent, 200);

// HTML Response พร้อม template
$templateData = ['title' => 'Home', 'content' => 'Welcome'];
$renderedHtml = $view->render('home', $templateData);
$htmlResponse = $response->html($renderedHtml);

การสร้าง Redirect Response

// Redirect responses
$redirectResponse = $response->redirect('/new-location'); // 302 Found
$permanentRedirect = $response->redirect('/new-location', 301); // 301 Moved Permanently

// Redirect พร้อม flash message
$redirectWithMessage = $response->redirect('/dashboard')
    ->withHeader('X-Flash-Message', 'Login successful');

การตั้งค่า Security Headers

// ตั้งค่า Security headers พื้นฐาน
$secureResponse = $response->setSecurityHeaders();

// หรือตั้งค่าเอง
$secureResponse = $response->withHeaders([
    'X-Content-Type-Options' => 'nosniff',
    'X-Frame-Options' => 'DENY',
    'X-XSS-Protection' => '1; mode=block',
    'Content-Security-Policy' => "default-src 'self'",
    'Strict-Transport-Security' => 'max-age=31536000; includeSubDomains'
]);

// ตั้งค่า CORS headers
$corsResponse = $response->setCorsHeaders();

// หรือตั้งค่า CORS แบบกำหนดเอง
$corsResponse = $response->withHeaders([
    'Access-Control-Allow-Origin' => '*',
    'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE, OPTIONS',
    'Access-Control-Allow-Headers' => 'Content-Type, Authorization'
]);

// ตั้งค่า No-cache headers
$noCacheResponse = $response->setNoCacheHeaders();

การสร้าง File Download Response

// File download
$fileContent = file_get_contents('/path/to/file.pdf');
$downloadResponse = $response->download($fileContent, 'document.pdf', 'application/pdf');

// File stream (สำหรับไฟล์ขนาดใหญ่)
$filePath = '/path/to/large-file.zip';
$fileResponse = $response->file($filePath, 'archive.zip');

// Image response
$imageContent = file_get_contents('/path/to/image.jpg');
$imageResponse = $response->withContent($imageContent)
    ->withHeader('Content-Type', 'image/jpeg')
    ->withHeader('Content-Disposition', 'inline; filename="image.jpg"');

การจัดการพารามิเตอร์และการตรวจสอบ

การตรวจสอบและ Validate พารามิเตอร์

class UserController
{
    public function updateProfile(Request $request): Response
    {
        $input = new Input($request);

        // การตรวจสอบพารามิเตอร์ที่จำเป็น
        $requiredParams = ['name', 'email'];
        foreach ($requiredParams as $param) {
            if (!$input->get($param)->exists()) {
                return Response::makeBadRequest([
                    'error' => "Missing required parameter: {$param}"
                ]);
            }
        }

        // การตรวจสอบรูปแบบข้อมูล
        $name = $input->getString('name');
        if (strlen($name) < 2) {
            return Response::makeBadRequest([
                'error' => 'Name must be at least 2 characters'
            ]);
        }

        $email = $input->getEmail('email');
        if (empty($email)) {
            return Response::makeBadRequest([
                'error' => 'Invalid email format'
            ]);
        }

        // ตรวจสอบ CSRF token
        if (!$input->validateCsrfToken($input->getString('csrf_token'))) {
            return Response::makeForbidden(['error' => 'Invalid CSRF token']);
        }

        // ประมวลผลข้อมูล
        $userData = [
            'name' => $name,
            'email' => $email,
            'phone' => $input->getPhone('phone'),
            'birth_date' => $input->getDate('birth_date'),
            'is_active' => $input->getBool('is_active', true)
        ];

        // บันทึกข้อมูล
        $this->userService->updateProfile($userData);

        return Response::makeOk(['message' => 'Profile updated successfully']);
    }
}

การจัดการ Pagination

class ProductController
{
    public function getProducts(Request $request): Response
    {
        $input = new Input($request);

        // การจัดการ pagination parameters
        $page = max(1, $input->getInt('page', 1));
        $limit = min(100, max(10, $input->getInt('limit', 20))); // จำกัด 10-100
        $sort = $input->getString('sort', 'created_at');
        $order = in_array($input->getString('order'), ['asc', 'desc'])
            ? $input->getString('order')
            : 'desc';

        // การกรองข้อมูล
        $filters = [];
        if ($input->get('category')->exists()) {
            $filters['category_id'] = $input->getInt('category');
        }
        if ($input->get('search')->exists()) {
            $filters['search'] = $input->getString('search');
        }
        if ($input->get('price_min')->exists()) {
            $filters['price_min'] = $input->getFloat('price_min');
        }
        if ($input->get('price_max')->exists()) {
            $filters['price_max'] = $input->getFloat('price_max');
        }

        // ดึงข้อมูล
        $offset = ($page - 1)  $limit;
        $products = $this->productService->getProducts($filters, $sort, $order, $limit, $offset);
        $total = $this->productService->countProducts($filters);

        // สร้าง pagination metadata
        $pagination = [
            'current_page' => $page,
            'per_page' => $limit,
            'total' => $total,
            'total_pages' => ceil($total / $limit),
            'has_more' => ($page  $limit) < $total
        ];

        return Response::makeOk([
            'products' => $products,
            'pagination' => $pagination,
            'filters' => $filters
        ]);
    }
}

การอัปโหลดไฟล์

การจัดการไฟล์อัปโหลดพื้นฐาน

class FileUploadController
{
    public function uploadAvatar(Request $request): Response
    {
        $input = new Input($request);

        // ตรวจสอบไฟล์อัปโหลด
        $uploadedFiles = $request->getUploadedFiles();
        if (!isset($uploadedFiles['avatar'])) {
            return Response::makeBadRequest(['error' => 'No file uploaded']);
        }

        $file = $uploadedFiles['avatar'];

        // ตรวจสอบ error
        if ($file->getError() !== UPLOAD_ERR_OK) {
            return Response::makeBadRequest(['error' => 'File upload failed']);
        }

        // ตรวจสอบขนาดไฟล์
$maxSize = 2; // 1024  1024; // 2MB
        if ($file->getSize() > $maxSize) {
            return Response::makeBadRequest(['error' => 'File too large']);
        }

        // ตรวจสอบประเภทไฟล์
        $allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
        $mimeType = $file->getClientMediaType();
        if (!in_array($mimeType, $allowedTypes)) {
            return Response::makeBadRequest(['error' => 'Invalid file type']);
        }

        // ตรวจสอบความปลอดภัยไฟล์
        if (!Validator::isFileSafe($file)) {
            return Response::makeBadRequest(['error' => 'File contains malicious content']);
        }

        // บันทึกไฟล์
        $filename = uniqid() . '_' . $file->getClientFilename();
        $uploadPath = '/uploads/avatars/' . $filename;
        $file->moveTo($uploadPath);

        // บันทึกข้อมูลในฐานข้อมูล
        $fileInfo = [
            'original_name' => $file->getClientFilename(),
            'filename' => $filename,
            'path' => $uploadPath,
            'size' => $file->getSize(),
            'mime_type' => $mimeType,
            'uploaded_at' => date('Y-m-d H:i:s')
        ];

        $fileId = $this->fileService->saveFileInfo($fileInfo);

        return Response::makeCreated([
            'file_id' => $fileId,
            'url' => '/uploads/avatars/' . $filename,
            'message' => 'File uploaded successfully'
        ]);
    }
}

การอัปโหลดไฟล์หลายไฟล์

class MultiFileUploadController
{
    public function uploadDocuments(Request $request): Response
    {
        $input = new Input($request);

        $uploadedFiles = $request->getUploadedFiles();
        if (!isset($uploadedFiles['documents']) || !is_array($uploadedFiles['documents'])) {
            return Response::makeBadRequest(['error' => 'No files uploaded']);
        }

        $files = $uploadedFiles['documents'];
        $uploadedFileInfo = [];
        $errors = [];

        foreach ($files as $index => $file) {
            try {
                // ตรวจสอบแต่ละไฟล์
                if ($file->getError() !== UPLOAD_ERR_OK) {
                    $errors[] = "File {$index}: Upload failed";
                    continue;
                }

                // ตรวจสอบขนาด
                if ($file->getSize() > 10  1024  1024) { // 10MB
                    $errors[] = "File {$index}: Too large";
                    continue;
                }

                // ตรวจสอบประเภท
                $allowedTypes = ['application/pdf', 'application/msword', 'text/plain'];
                if (!in_array($file->getClientMediaType(), $allowedTypes)) {
                    $errors[] = "File {$index}: Invalid type";
                    continue;
                }

                // บันทึกไฟล์
                $filename = uniqid() . '_' . $file->getClientFilename();
                $uploadPath = '/uploads/documents/' . $filename;
                $file->moveTo($uploadPath);

                $uploadedFileInfo[] = [
                    'original_name' => $file->getClientFilename(),
                    'filename' => $filename,
                    'path' => $uploadPath,
                    'size' => $file->getSize(),
                    'mime_type' => $file->getClientMediaType()
                ];

            } catch (Exception $e) {
                $errors[] = "File {$index}: {$e->getMessage()}";
            }
        }

        if (empty($uploadedFileInfo) && !empty($errors)) {
            return Response::makeBadRequest([
                'error' => 'No files were uploaded successfully',
                'details' => $errors
            ]);
        }

        return Response::makeOk([
            'uploaded_files' => $uploadedFileInfo,
            'errors' => $errors,
            'message' => count($uploadedFileInfo) . ' files uploaded successfully'
        ]);
    }
}

การจัดรูปแบบการตอบกลับ

API Response Format Standards

class ApiResponseFormatter
{
    /
      สร้าง Success Response แบบมาตรฐาน
     /
    public static function success($data = null, string $message = 'Success', int $status = 200): Response
    {
        $response = [
            'success' => true,
            'message' => $message,
            'timestamp' => date('c'),
            'request_id' => uniqid()
        ];

        if ($data !== null) {
            $response['data'] = $data;
        }

        return Response::makeJson($response, $status);
    }

    /
      สร้าง Error Response แบบมาตรฐาน
     /
    public static function error(string $message, int $status = 400, array $errors = [], $code = null): Response
    {
        $response = [
            'success' => false,
            'message' => $message,
            'timestamp' => date('c'),
            'request_id' => uniqid()
        ];

        if (!empty($errors)) {
            $response['errors'] = $errors;
        }

        if ($code !== null) {
            $response['error_code'] = $code;
        }

        return Response::makeJson($response, $status);
    }

    /
      สร้าง Paginated Response
     /
    public static function paginated(array $items, int $total, int $page, int $limit, string $message = 'Data retrieved'): Response
    {
        $totalPages = ceil($total / $limit);

        $data = [
            'items' => $items,
            'pagination' => [
                'current_page' => $page,
                'per_page' => $limit,
                'total_items' => $total,
                'total_pages' => $totalPages,
                'has_next' => $page < $totalPages,
                'has_prev' => $page > 1,
                'next_page' => $page < $totalPages ? $page + 1 : null,
                'prev_page' => $page > 1 ? $page - 1 : null
            ]
        ];

        return self::success($data, $message);
    }

    /
      สร้าง Validation Error Response
     /
    public static function validationError(array $errors, string $message = 'Validation failed'): Response
    {
        return self::error($message, 422, $errors, 'VALIDATION_ERROR');
    }
}

// การใช้งาน
class UserApiController
{
    public function getUsers(Request $request): Response
    {
        $input = new Input($request);

        try {
            $page = $input->getInt('page', 1);
            $limit = $input->getInt('limit', 20);

            $users = $this->userService->getUsers($page, $limit);
            $total = $this->userService->getTotalUsers();

            return ApiResponseFormatter::paginated($users, $total, $page, $limit);

        } catch (Exception $e) {
            return ApiResponseFormatter::error('Failed to retrieve users', 500, [], 'SERVER_ERROR');
        }
    }

    public function createUser(Request $request): Response
    {
        $input = new Input($request);

        // Validation
        $validation = $this->validateUserInput($input);
        if (!empty($validation['errors'])) {
            return ApiResponseFormatter::validationError($validation['errors']);
        }

        try {
            $user = $this->userService->createUser($validation['data']);
            return ApiResponseFormatter::success($user, 'User created successfully', 201);

        } catch (Exception $e) {
            return ApiResponseFormatter::error('Failed to create user', 500);
        }
    }
}

Content Negotiation

class ContentNegotiationController
{
    public function getResource(Request $request): Response
    {
        $input = new Input($request);
        $acceptHeader = $request->getHeaderLine('Accept');

        // ดึงข้อมูล
        $data = $this->resourceService->getData();

        // การตัดสินใจรูปแบบการตอบกลับตาม Accept header
        if (strpos($acceptHeader, 'application/json') !== false) {
            return Response::makeJson($data);
        }
        elseif (strpos($acceptHeader, 'application/xml') !== false) {
            $xml = $this->convertToXml($data);
            return (new Response())
                ->withContent($xml)
                ->withHeader('Content-Type', 'application/xml');
        }
        elseif (strpos($acceptHeader, 'text/csv') !== false) {
            $csv = $this->convertToCsv($data);
            return (new Response())
                ->withContent($csv)
                ->withHeader('Content-Type', 'text/csv')
                ->withHeader('Content-Disposition', 'attachment; filename="data.csv"');
        }
        else {
            // Default to HTML
            $html = $this->renderHtml($data);
            return (new Response())->html($html);
        }
    }

    private function convertToXml(array $data): string
    {
        $xml = new SimpleXMLElement('<root/>');
        array_walk_recursive($data, function($value, $key) use ($xml) {
            $xml->addChild($key, htmlspecialchars($value));
        });
        return $xml->asXML();
    }

    private function convertToCsv(array $data): string
    {
        $output = fopen('php://temp', 'w');

        if (!empty($data)) {
            // Write header
            fputcsv($output, array_keys($data[0]));

            // Write data
            foreach ($data as $row) {
                fputcsv($output, $row);
            }
        }

        rewind($output);
        $csv = stream_get_contents($output);
        fclose($output);

        return $csv;
    }
}

ตัวอย่างการใช้งานในระบบจริง

ระบบ REST API สำหรับจัดการผู้ใช้

class UserRestController
{
    private $userService;

    public function __construct(UserService $userService)
    {
        $this->userService = $userService;
    }

    /
      GET /api/users - ดึงรายชื่อผู้ใช้
     /
    public function index(Request $request): Response
    {
        $input = new Input($request);

        // การจัดการ query parameters
        $filters = [
            'search' => $input->getString('search', ''),
            'role' => $input->getString('role', ''),
            'status' => $input->getString('status', 'active'),
            'created_from' => $input->getDate('created_from'),
            'created_to' => $input->getDate('created_to')
        ];

        $page = max(1, $input->getInt('page', 1));
        $limit = min(100, max(10, $input->getInt('limit', 20)));
        $sort = $input->getString('sort', 'created_at');
        $order = in_array($input->getString('order'), ['asc', 'desc']) ? $input->getString('order') : 'desc';

        try {
            $users = $this->userService->getUsers($filters, $sort, $order, $limit, $page);
            $total = $this->userService->countUsers($filters);

            return ApiResponseFormatter::paginated($users, $total, $page, $limit);

        } catch (Exception $e) {
            return ApiResponseFormatter::error('Failed to retrieve users', 500);
        }
    }

    /
      GET /api/users/{id} - ดึงข้อมูลผู้ใช้รายคน
     /
    public function show(Request $request, int $id): Response
    {
        try {
            $user = $this->userService->getUserById($id);

            if (!$user) {
                return ApiResponseFormatter::error('User not found', 404, [], 'USER_NOT_FOUND');
            }

            return ApiResponseFormatter::success($user, 'User retrieved successfully');

        } catch (Exception $e) {
            return ApiResponseFormatter::error('Failed to retrieve user', 500);
        }
    }

    /
      POST /api/users - สร้างผู้ใช้ใหม่
     /
    public function store(Request $request): Response
    {
        $input = new Input($request);

        // ตรวจสอบ CSRF token
        if (!$input->validateCsrfToken($input->getString('csrf_token'))) {
            return ApiResponseFormatter::error('Invalid CSRF token', 403, [], 'CSRF_ERROR');
        }

        // Validation rules
        $rules = [
            'username' => 'required|min:3|max:20|alphanumeric',
            'email' => 'required|email|unique:users',
            'password' => 'required|min:8|password_strength',
            'first_name' => 'required|min:2|max:50',
            'last_name' => 'required|min:2|max:50',
            'role' => 'required|in:admin,user,moderator'
        ];

        $validation = $this->validateInput($input, $rules);
        if (!$validation['valid']) {
            return ApiResponseFormatter::validationError($validation['errors']);
        }

        try {
            $userData = [
                'username' => $input->getString('username'),
                'email' => $input->getEmail('email'),
                'password' => password_hash($input->getString('password'), PASSWORD_DEFAULT),
                'first_name' => $input->getString('first_name'),
                'last_name' => $input->getString('last_name'),
                'role' => $input->getString('role'),
                'created_at' => date('Y-m-d H:i:s')
            ];

            $user = $this->userService->createUser($userData);

            return ApiResponseFormatter::success($user, 'User created successfully', 201);

        } catch (Exception $e) {
            return ApiResponseFormatter::error('Failed to create user', 500);
        }
    }

    /
      PUT /api/users/{id} - อัพเดทข้อมูลผู้ใช้
     /
    public function update(Request $request, int $id): Response
    {
        $input = new Input($request);

        // ตรวจสอบว่าผู้ใช้มีอยู่
        $existingUser = $this->userService->getUserById($id);
        if (!$existingUser) {
            return ApiResponseFormatter::error('User not found', 404, [], 'USER_NOT_FOUND');
        }

        // ตรวจสอบสิทธิ์การแก้ไข
        if (!$this->canEditUser($request, $id)) {
            return ApiResponseFormatter::error('Access denied', 403, [], 'ACCESS_DENIED');
        }

        // Validation (บางฟิลด์เป็น optional สำหรับ update)
        $rules = [
            'email' => 'email|unique:users,email,' . $id,
            'first_name' => 'min:2|max:50',
            'last_name' => 'min:2|max:50',
            'role' => 'in:admin,user,moderator'
        ];

        $validation = $this->validateInput($input, $rules);
        if (!$validation['valid']) {
            return ApiResponseFormatter::validationError($validation['errors']);
        }

        try {
            $updateData = [];

            // อัพเดทเฉพาะฟิลด์ที่ส่งมา
            if ($input->get('email')->exists()) {
                $updateData['email'] = $input->getEmail('email');
            }
            if ($input->get('first_name')->exists()) {
                $updateData['first_name'] = $input->getString('first_name');
            }
            if ($input->get('last_name')->exists()) {
                $updateData['last_name'] = $input->getString('last_name');
            }
            if ($input->get('role')->exists()) {
                $updateData['role'] = $input->getString('role');
            }

            // อัพเดทรหัสผ่านถ้ามี
            if ($input->get('password')->exists()) {
                $password = $input->getString('password');
                if (strlen($password) >= 8) {
                    $updateData['password'] = password_hash($password, PASSWORD_DEFAULT);
                }
            }

            $updateData['updated_at'] = date('Y-m-d H:i:s');

            $updatedUser = $this->userService->updateUser($id, $updateData);

            return ApiResponseFormatter::success($updatedUser, 'User updated successfully');

        } catch (Exception $e) {
            return ApiResponseFormatter::error('Failed to update user', 500);
        }
    }

    /
      DELETE /api/users/{id} - ลบผู้ใช้
     /
    public function destroy(Request $request, int $id): Response
    {
        // ตรวจสอบว่าผู้ใช้มีอยู่
        $user = $this->userService->getUserById($id);
        if (!$user) {
            return ApiResponseFormatter::error('User not found', 404, [], 'USER_NOT_FOUND');
        }

        // ตรวจสอบสิทธิ์การลบ
        if (!$this->canDeleteUser($request, $id)) {
            return ApiResponseFormatter::error('Access denied', 403, [], 'ACCESS_DENIED');
        }

        try {
            $this->userService->deleteUser($id);

            return ApiResponseFormatter::success(null, 'User deleted successfully');

        } catch (Exception $e) {
            return ApiResponseFormatter::error('Failed to delete user', 500);
        }
    }

    private function validateInput(Input $input, array $rules): array
    {
        $input->rules($rules);
        $valid = $input->validate();

        return [
            'valid' => $valid,
            'errors' => $valid ? [] : $input->errors(),
            'data' => $valid ? $input->validated() : []
        ];
    }

    private function canEditUser(Request $request, int $userId): bool
    {
        // ตรวจสอบสิทธิ์จาก JWT token หรือ session
        $currentUserId = $this->getCurrentUserId($request);
        $currentUserRole = $this->getCurrentUserRole($request);

        // Admin สามารถแก้ไขได้ทุกคน, user แก้ไขได้เฉพาะตัวเอง
        return $currentUserRole === 'admin' || $currentUserId === $userId;
    }

    private function canDeleteUser(Request $request, int $userId): bool
    {
        $currentUserRole = $this->getCurrentUserRole($request);
        return $currentUserRole === 'admin';
    }
}

ระบบอัปโหลดและจัดการไฟล์

class FileManagementController
{
    /
      POST /api/files/upload - อัปโหลดไฟล์
     /
    public function upload(Request $request): Response
    {
        $input = new Input($request);

        // ตรวจสอบสิทธิ์การอัปโหลด
        if (!$this->canUpload($request)) {
            return ApiResponseFormatter::error('Upload permission denied', 403);
        }

        $uploadedFiles = $request->getUploadedFiles();
        if (empty($uploadedFiles['file'])) {
            return ApiResponseFormatter::error('No file uploaded', 400);
        }

        $file = $uploadedFiles['file'];

        // ตรวจสอบไฟล์
        $validation = $this->validateFile($file, $input);
        if (!$validation['valid']) {
            return ApiResponseFormatter::validationError($validation['errors']);
        }

        try {
            // สร้าง unique filename
            $extension = pathinfo($file->getClientFilename(), PATHINFO_EXTENSION);
            $filename = uniqid() . '_' . time() . '.' . $extension;

            // กำหนด upload path ตามประเภทไฟล์
            $uploadDir = $this->getUploadDirectory($file->getClientMediaType());
            $fullPath = $uploadDir . '/' . $filename;

            // ย้ายไฟล์
            $file->moveTo($fullPath);

            // บันทึกข้อมูลในฐานข้อมูล
            $fileData = [
                'original_name' => $file->getClientFilename(),
                'filename' => $filename,
                'path' => $fullPath,
                'size' => $file->getSize(),
                'mime_type' => $file->getClientMediaType(),
                'uploaded_by' => $this->getCurrentUserId($request),
                'upload_ip' => $request->server('REMOTE_ADDR'),
                'created_at' => date('Y-m-d H:i:s')
            ];

            $fileId = $this->fileService->saveFile($fileData);

            // สร้าง thumbnail สำหรับรูปภาพ
            if (strpos($file->getClientMediaType(), 'image/') === 0) {
                $this->createThumbnail($fullPath, $filename);
            }

            return ApiResponseFormatter::success([
                'file_id' => $fileId,
                'filename' => $filename,
                'original_name' => $file->getClientFilename(),
                'size' => $file->getSize(),
                'url' => $this->getFileUrl($filename),
                'thumbnail_url' => $this->getThumbnailUrl($filename)
            ], 'File uploaded successfully', 201);

        } catch (Exception $e) {
            return ApiResponseFormatter::error('Upload failed: ' . $e->getMessage(), 500);
        }
    }

    /
      GET /api/files/{id}/download - ดาวน์โหลดไฟล์
     /
    public function download(Request $request, int $fileId): Response
    {
        try {
            $file = $this->fileService->getFileById($fileId);

            if (!$file) {
                return ApiResponseFormatter::error('File not found', 404);
            }

            // ตรวจสอบสิทธิ์การดาวน์โหลด
            if (!$this->canDownload($request, $file)) {
                return ApiResponseFormatter::error('Download permission denied', 403);
            }

            // ตรวจสอบไฟล์จริงบนระบบ
            if (!file_exists($file['path'])) {
                return ApiResponseFormatter::error('File not found on disk', 404);
            }

            // อัพเดท download count
            $this->fileService->incrementDownloadCount($fileId);

            // ส่งไฟล์
            $response = new Response();
            return $response->file($file['path'], $file['original_name']);

        } catch (Exception $e) {
            return ApiResponseFormatter::error('Download failed', 500);
        }
    }

    /
      GET /api/files - รายการไฟล์
     /
    public function index(Request $request): Response
    {
        $input = new Input($request);

        $filters = [
            'mime_type' => $input->getString('type', ''),
            'search' => $input->getString('search', ''),
            'uploaded_by' => $input->getInt('user_id', 0),
            'date_from' => $input->getDate('date_from'),
            'date_to' => $input->getDate('date_to')
        ];

        $page = max(1, $input->getInt('page', 1));
        $limit = min(50, max(10, $input->getInt('limit', 20)));

        try {
            $files = $this->fileService->getFiles($filters, $page, $limit);
            $total = $this->fileService->countFiles($filters);

            // เพิ่มข้อมูล URL สำหรับแต่ละไฟล์
            $filesWithUrls = array_map(function($file) {
                $file['url'] = $this->getFileUrl($file['filename']);
                $file['thumbnail_url'] = $this->getThumbnailUrl($file['filename']);
                return $file;
            }, $files);

            return ApiResponseFormatter::paginated($filesWithUrls, $total, $page, $limit);

        } catch (Exception $e) {
            return ApiResponseFormatter::error('Failed to retrieve files', 500);
        }
    }

    private function validateFile($file, Input $input): array
    {
        $errors = [];

        // ตรวจสอบ upload error
        if ($file->getError() !== UPLOAD_ERR_OK) {
            $errors[] = 'File upload failed with error code: ' . $file->getError();
            return ['valid' => false, 'errors' => $errors];
        }

        // ตรวจสอบขนาดไฟล์
        $maxSize = $this->getMaxFileSize($file->getClientMediaType());
        if ($file->getSize() > $maxSize) {
            $errors[] = 'File size exceeds limit of ' . ($maxSize / 1024 / 1024) . 'MB';
        }

        // ตรวจสอบประเภทไฟล์
        $allowedTypes = $this->getAllowedFileTypes();
        if (!in_array($file->getClientMediaType(), $allowedTypes)) {
            $errors[] = 'File type not allowed: ' . $file->getClientMediaType();
        }

        // ตรวจสอบความปลอดภัย
        if (!Validator::isFileSafe($file)) {
            $errors[] = 'File contains potentially malicious content';
        }

        // ตรวจสอบขนาดรูปภาพ (ถ้าเป็นรูปภาพ)
        if (strpos($file->getClientMediaType(), 'image/') === 0) {
            $imageInfo = getimagesize($file->getStream()->getMetadata('uri'));
            if ($imageInfo) {
                $maxWidth = 4000;
                $maxHeight = 4000;
                if ($imageInfo[0] > $maxWidth || $imageInfo[1] > $maxHeight) {
                    $errors[] = "Image dimensions too large. Max: {$maxWidth}x{$maxHeight}";
                }
            }
        }

        return [
            'valid' => empty($errors),
            'errors' => $errors
        ];
    }
}

ระบบ Input และ Request ของ Kotchasan Framework มีความสมบูรณ์และทันสมัย รองรับการพัฒนาแอปพลิเคชันเว็บที่ปลอดภัยและมีประสิทธิภาพสูง ด้วยการรองรับ PSR-7 และฟีเจอร์เพิ่มเติมที่จำเป็นสำหรับการใช้งานจริง