Kotchasan Framework Documentation

Kotchasan Framework Documentation

คลาส Files - คอลเลกชันไฟล์อัปโหลด

TH 05 Feb 2026 07:40

คลาส Files - คอลเลกชันไฟล์อัปโหลด

คลาส Files เป็น Iterator สำหรับจัดการคอลเลกชันของไฟล์ที่อัปโหลด โดยใช้ร่วมกับ UploadedFile ภายใน Kotchasan Framework

Namespace

Kotchasan\Files

ภาพรวม

Files class implement \Iterator interface ทำให้สามารถใช้ในลูป foreach ได้

API Reference

__construct()

สร้าง instance ใหม่ของคอลเลกชันไฟล์

public function __construct()

Example:

use Kotchasan\Files;

// สร้างคอลเลกชันไฟล์ใหม่
$files = new Files();

add()

เพิ่มไฟล์เข้าในคอลเลกชัน

public function add($name, $path, $originalName, $mimeType = null, $size = null, $error = null)

Parameters:

  • $name - ชื่อ input
  • $path - พาธไฟล์ที่อัปโหลด
  • $originalName - ชื่อไฟล์ต้นฉบับ
  • $mimeType - MIME Type (optional)
  • $size - ขนาดไฟล์ (optional)
  • $error - รหัสข้อผิดพลาด UPLOAD_ERR_XXX (optional)

Returns: void

Example:

use Kotchasan\Files;

$files = new Files();

// เพิ่มไฟล์รูปภาพ
$files->add('profile_image', '/tmp/upload123', 'avatar.jpg', 'image/jpeg', 1024000, UPLOAD_ERR_OK);

// เพิ่มไฟล์เอกสาร
$files->add('document', '/tmp/upload124', 'resume.pdf', 'application/pdf', 2048000, UPLOAD_ERR_OK);

// เพิ่มไฟล์ที่มีข้อผิดพลาด
$files->add('large_file', '/tmp/upload125', 'video.mp4', 'video/mp4', 50000000, UPLOAD_ERR_FORM_SIZE);

// ใช้กับข้อมูลจาก $_FILES
foreach ($_FILES as $inputName => $fileData) {
    if (is_array($fileData['name'])) {
        // Multiple files
        for ($i = 0; $i < count($fileData['name']); $i++) {
            $files->add(
                $inputName,
                $fileData['tmp_name'][$i],
                $fileData['name'][$i],
                $fileData['type'][$i],
                $fileData['size'][$i],
                $fileData['error'][$i]
            );
        }
    } else {
        // Single file
        $files->add(
            $inputName,
            $fileData['tmp_name'],
            $fileData['name'],
            $fileData['type'],
            $fileData['size'],
            $fileData['error']
        );
    }
}

get()

ดึงไฟล์ตามคีย์ที่ระบุ

public function get($key)

Parameters:

  • $key (string|int) - คีย์ที่ต้องการ

Returns: \Kotchasan\Http\UploadedFile|null - UploadedFile object หรือ null ถ้าไม่พบ

Example:

use Kotchasan\Files;

$files = new Files();
$files->add('profile', '/tmp/upload123', 'avatar.jpg', 'image/jpeg', 1024000, UPLOAD_ERR_OK);
$files->add('document', '/tmp/upload124', 'resume.pdf', 'application/pdf', 2048000, UPLOAD_ERR_OK);

// ดึงไฟล์โปรไฟล์
$profileFile = $files->get('profile');
if ($profileFile) {
    echo "โปรไฟล์: " . $profileFile->getClientFilename();
    echo "ขนาด: " . $profileFile->getSize() . " bytes";
}

// ดึงไฟล์เอกสาร
$documentFile = $files->get('document');
if ($documentFile) {
    echo "เอกสาร: " . $documentFile->getClientFilename();
    echo "ประเภท: " . $documentFile->getClientMediaType();
}

// ตรวจสอบไฟล์ที่ไม่มี
$missingFile = $files->get('nonexistent');
if ($missingFile === null) {
    echo "ไม่พบไฟล์ที่ระบุ";
}

Iterator Methods

คลาส Files implement Iterator interface เพื่อให้สามารถใช้ในลูป foreach ได้

public function rewind()          // เริ่มต้นใหม่
public function valid()            // ตรวจสอบว่ามีข้อมูลหรือไม่ (returns bool)
public function current()          // ดึงไฟล์ปัจจุบัน (returns UploadedFile)
public function key()              // ดึงคีย์ปัจจุบัน (returns string)
public function next()             // ไปยังไฟล์ถัดไป

Example:

use Kotchasan\Files;
use Kotchasan\File;

$files = new Files();
$files->add('image1', '/tmp/upload1', 'photo1.jpg', 'image/jpeg', 1024000, UPLOAD_ERR_OK);
$files->add('image2', '/tmp/upload2', 'photo2.png', 'image/png', 2048000, UPLOAD_ERR_OK);
$files->add('document', '/tmp/upload3', 'doc.pdf', 'application/pdf', 3072000, UPLOAD_ERR_OK);

// วนลูปผ่านไฟล์ทั้งหมด
foreach ($files as $inputName => $uploadedFile) {
    echo "Input: {$inputName}\n";
    echo "ชื่อไฟล์: " . $uploadedFile->getClientFilename() . "\n";
    echo "ขนาด: " . $uploadedFile->getSize() . " bytes\n";
    echo "ประเภท: " . $uploadedFile->getClientMediaType() . "\n";
    echo "สถานะ: " . ($uploadedFile->getError() === UPLOAD_ERR_OK ? 'สำเร็จ' : 'ผิดพลาด') . "\n";
    echo "---\n";
}

// ตัวอย่างการประมวลผลไฟล์ทั้งหมด
function processAllFiles($files) {
    $results = [];

    foreach ($files as $inputName => $uploadedFile) {
        $result = [
            'input_name' => $inputName,
            'original_name' => $uploadedFile->getClientFilename(),
            'size' => $uploadedFile->getSize(),
            'type' => $uploadedFile->getClientMediaType(),
            'error' => $uploadedFile->getError(),
            'processed' => false,
            'message' => ''
        ];

        if ($uploadedFile->getError() === UPLOAD_ERR_OK) {
            // ประมวลผลไฟล์
            $extension = File::ext($uploadedFile->getClientFilename());
            $allowedTypes = ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx'];

            if (in_array($extension, $allowedTypes)) {
                $result['processed'] = true;
                $result['message'] = 'ไฟล์ถูกประมวลผลสำเร็จ';
            } else {
                $result['message'] = 'ประเภทไฟล์ไม่ได้รับอนุญาต';
            }
        } else {
            $result['message'] = 'ข้อผิดพลาดในการอัปโหลด: ' . $uploadedFile->getError();
        }

        $results[] = $result;
    }

    return $results;
}

// ตัวอย่างการกรองไฟล์
function filterFilesByType($files, $allowedTypes) {
    $filtered = new Files();

    foreach ($files as $inputName => $uploadedFile) {
        $extension = File::ext($uploadedFile->getClientFilename());

        if (in_array($extension, $allowedTypes)) {
            $filtered->add(
                $inputName,
                $uploadedFile->getStream()->getMetadata('uri'),
                $uploadedFile->getClientFilename(),
                $uploadedFile->getClientMediaType(),
                $uploadedFile->getSize(),
                $uploadedFile->getError()
            );
        }
    }

    return $filtered;
}

// ตัวอย่างการสร้างรายงานไฟล์
function generateUploadReport($files) {
    $report = [
        'total_files' => 0,
        'successful_uploads' => 0,
        'failed_uploads' => 0,
        'total_size' => 0,
        'file_types' => [],
        'errors' => []
    ];

    foreach ($files as $inputName => $uploadedFile) {
        $report['total_files']++;

        if ($uploadedFile->getError() === UPLOAD_ERR_OK) {
            $report['successful_uploads']++;
            $report['total_size'] += $uploadedFile->getSize();

            $extension = File::ext($uploadedFile->getClientFilename());
            $report['file_types'][$extension] = ($report['file_types'][$extension] ?? 0) + 1;
        } else {
            $report['failed_uploads']++;
            $report['errors'][] = [
                'input_name' => $inputName,
                'filename' => $uploadedFile->getClientFilename(),
                'error_code' => $uploadedFile->getError()
            ];
        }
    }

    return $report;
}

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

1. ระบบจัดการอัปโหลดรูปภาพ

use Kotchasan\Files;
use Kotchasan\File;
use Kotchasan\Image;

class ImageUploadManager
{
    public static function processImageUploads($files, $uploadDir)
    {
        $results = [];

        foreach ($files as $inputName => $uploadedFile) {
            if ($uploadedFile->getError() !== UPLOAD_ERR_OK) {
                $results[] = [
                    'input_name' => $inputName,
                    'success' => false,
                    'message' => 'ข้อผิดพลาดในการอัปโหลด: ' . $uploadedFile->getError()
                ];
                continue;
            }

            $extension = File::ext($uploadedFile->getClientFilename());
            if (!in_array($extension, ['jpg', 'jpeg', 'png', 'gif'])) {
                $results[] = [
                    'input_name' => $inputName,
                    'success' => false,
                    'message' => 'ประเภทไฟล์ไม่ใช่รูปภาพ'
                ];
                continue;
            }

            // สร้างชื่อไฟล์ใหม่
            $newFilename = uniqid() . '.' . $extension;
            $targetPath = $uploadDir . $newFilename;

            // ย้ายไฟล์
            $uploadedFile->moveTo($targetPath);

            // สร้าง thumbnail
            $thumbnailPath = $uploadDir . 'thumbs/' . $newFilename;
            File::makeDirectory(dirname($thumbnailPath));
            Image::crop($targetPath, $thumbnailPath, 200, 200);

            $results[] = [
                'input_name' => $inputName,
                'success' => true,
                'original_name' => $uploadedFile->getClientFilename(),
                'saved_name' => $newFilename,
                'path' => $targetPath,
                'thumbnail' => $thumbnailPath,
                'size' => $uploadedFile->getSize()
            ];
        }

        return $results;
    }
}

2. ระบบจัดการอัปโหลดเอกสาร

class DocumentUploadManager
{
    public static function processDocumentUploads($files, $uploadDir, $userId)
    {
        $userDir = $uploadDir . "user_{$userId}/";
        File::makeDirectory($userDir);

        $results = [];

        foreach ($files as $inputName => $uploadedFile) {
            if ($uploadedFile->getError() !== UPLOAD_ERR_OK) {
                $results[] = [
                    'input_name' => $inputName,
                    'success' => false,
                    'message' => 'ข้อผิดพลาดในการอัปโหลด'
                ];
                continue;
            }

            $extension = File::ext($uploadedFile->getClientFilename());
            $allowedTypes = ['pdf', 'doc', 'docx', 'txt', 'xls', 'xlsx'];

            if (!in_array($extension, $allowedTypes)) {
                $results[] = [
                    'input_name' => $inputName,
                    'success' => false,
                    'message' => 'ประเภทเอกสารไม่ได้รับอนุญาต'
                ];
                continue;
            }

            // ตรวจสอบขนาดไฟล์ (10MB max)
            if ($uploadedFile->getSize() > 10 * 1024  * 1024) {
                $results[] = [
                    'input_name' => $inputName,
                    'success' => false,
                    'message' => 'ไฟล์มีขนาดใหญ่เกินกำหนด (สูงสุด 10MB)'
                ];
                continue;
            }

            $safeFilename = date('Y-m-d_H-i-s') . '_' . $uploadedFile->getClientFilename();
            $targetPath = $userDir . $safeFilename;

            $uploadedFile->moveTo($targetPath);

            $results[] = [
                'input_name' => $inputName,
                'success' => true,
                'original_name' => $uploadedFile->getClientFilename(),
                'saved_name' => $safeFilename,
                'path' => $targetPath,
                'size' => $uploadedFile->getSize(),
                'type' => $uploadedFile->getClientMediaType()
            ];
        }

        return $results;
    }
}

3. ระบบอัปโหลดไฟล์แบบหลายไฟล์

class MultiFileUploader
{
    public function handleUpload()
    {
        $files = new Files();

        // ประมวลผลข้อมูลจาก $_FILES
        foreach ($_FILES as $inputName => $fileData) {
            if (is_array($fileData['name'])) {
                // หลายไฟล์
                for ($i = 0; $i < count($fileData['name']); $i++) {
                    if (!empty($fileData['name'][$i])) {
                        $files->add(
                            $inputName . '[' . $i . ']',
                            $fileData['tmp_name'][$i],
                            $fileData['name'][$i],
                            $fileData['type'][$i],
                            $fileData['size'][$i],
                            $fileData['error'][$i]
                        );
                    }
                }
            } else {
                // ไฟล์เดียว
                if (!empty($fileData['name'])) {
                    $files->add(
                        $inputName,
                        $fileData['tmp_name'],
                        $fileData['name'],
                        $fileData['type'],
                        $fileData['size'],
                        $fileData['error']
                    );
                }
            }
        }

        return $this->processFiles($files);
    }

    private function processFiles($files)
    {
        $uploadDir = ROOT_PATH . 'datas/uploads/' . date('Y/m/d') . '/';
        File::makeDirectory($uploadDir);

        $results = [
            'uploaded' => [],
            'failed' => [],
            'summary' => [
                'total' => 0,
                'success' => 0,
                'failed' => 0
            ]
        ];

        foreach ($files as $inputName => $uploadedFile) {
            $results['summary']['total']++;

            $result = $this->processFile($uploadedFile, $uploadDir);
            $result['input_name'] = $inputName;

            if ($result['success']) {
                $results['uploaded'][] = $result;
                $results['summary']['success']++;
            } else {
                $results['failed'][] = $result;
                $results['summary']['failed']++;
            }
        }

        return $results;
    }

    private function processFile($uploadedFile, $uploadDir)
    {
        if ($uploadedFile->getError() !== UPLOAD_ERR_OK) {
            return [
                'success' => false,
                'message' => $this->getUploadErrorMessage($uploadedFile->getError()),
                'original_name' => $uploadedFile->getClientFilename()
            ];
        }

        $extension = File::ext($uploadedFile->getClientFilename());
        $allowedTypes = ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx'];

        if (!in_array($extension, $allowedTypes)) {
            return [
                'success' => false,
                'message' => 'ประเภทไฟล์ไม่ได้รับอนุญาต',
                'original_name' => $uploadedFile->getClientFilename()
            ];
        }

        $filename = uniqid() . '_' . $uploadedFile->getClientFilename();
        $targetPath = $uploadDir . $filename;

        try {
            $uploadedFile->moveTo($targetPath);

            return [
                'success' => true,
                'message' => 'อัปโหลดสำเร็จ',
                'original_name' => $uploadedFile->getClientFilename(),
                'saved_name' => $filename,
                'path' => $targetPath,
                'size' => $uploadedFile->getSize(),
                'url' => str_replace(ROOT_PATH, WEB_URL, $targetPath)
            ];
        } catch (Exception $e) {
            return [
                'success' => false,
                'message' => 'ไม่สามารถบันทึกไฟล์ได้: ' . $e->getMessage(),
                'original_name' => $uploadedFile->getClientFilename()
            ];
        }
    }

    private function getUploadErrorMessage($errorCode)
    {
        $messages = [
            UPLOAD_ERR_INI_SIZE => 'ไฟล์มีขนาดใหญ่เกินกำหนดในระบบ',
            UPLOAD_ERR_FORM_SIZE => 'ไฟล์มีขนาดใหญ่เกินกำหนดในฟอร์ม',
            UPLOAD_ERR_PARTIAL => 'ไฟล์ถูกอัปโหลดไม่สมบูรณ์',
            UPLOAD_ERR_NO_FILE => 'ไม่มีไฟล์ถูกอัปโหลด',
            UPLOAD_ERR_NO_TMP_DIR => 'ไม่พบไดเรกทอรีชั่วคราว',
            UPLOAD_ERR_CANT_WRITE => 'ไม่สามารถเขียนไฟล์ลงดิสก์ได้',
            UPLOAD_ERR_EXTENSION => 'การอัปโหลดถูกหยุดโดย extension'
        ];

        return $messages[$errorCode] ?? 'ข้อผิดพลาดไม่ทราบสาเหตุ';
    }
}

// การใช้งานในคอนโทรลเลอร์
class UploadController extends \Kotchasan\Controller
{
    public function upload()
    {
        if ($this->request->getMethod() === 'POST') {
            $uploader = new MultiFileUploader();
            $results = $uploader->handleUpload();

            // ส่งผลลัพธ์กลับเป็น JSON
            header('Content-Type: application/json');
            echo json_encode($results);
        } else {
            // แสดงฟอร์มอัปโหลด
            include ROOT_PATH . 'modules/upload/views/form.php';
        }
    }
}

หมายเหตุการใช้งาน

  1. Iterator Pattern: สามารถใช้ในลูป foreach ได้โดยตรง
  2. UploadedFile: ทำงานร่วมกับ PSR-7 UploadedFile interface
  3. Memory Efficient: เก็บเฉพาะ reference ไม่โหลดไฟล์ทั้งหมดเข้า memory
  4. Flexible: รองรับทั้งไฟล์เดียวและหลายไฟล์

คลาสที่เกี่ยวข้อง

  • [File] - File และ directory management
  • Image - Image processing
  • UploadedFile - PSR-7 UploadedFile

สรุป

Files class มี 6 เมธอดหลัก:

  1. __construct() - สร้าง file collection
  2. add() - เพิ่มไฟล์เข้า collection
  3. get() - ดึงไฟล์ตาม key
  4. rewind() - เริ่มต้น iterator ใหม่
  5. valid() - ตรวจสอบว่ามีข้อมูล
  6. current(), key(), next() - Iterator methods

เหมาะสำหรับ:

  • ระบบอัปโหลดรูปภาพ
  • ระบบอัปโหลดเอกสาร
  • ระบบอัปโหลดหลายไฟล์
  • ระบบจัดการไฟล์ผู้ใช้