Kotchasan Framework Documentation

Kotchasan Framework Documentation

คลาส Input - การจัดการและตรวจสอบข้อมูล

TH 03 Feb 2026 15:06

คลาส Input - การจัดการและตรวจสอบข้อมูล

คลาส Input เป็นคลาสหลักสำหรับจัดการข้อมูลที่เข้ามาจากผู้ใช้ รองรับการรับข้อมูลจากหลายแหล่ง การตรวจสอบความถูกต้อง การทำความสะอาดข้อมูล และการจัดการไฟล์อัปโหลด พร้อมรองรับมาตรฐาน PSR-7

Namespace

Kotchasan\Input

ภาพรวม

Input class ให้เครื่องมือครบครอบสำหรับ:

  • รับข้อมูลจาก POST, GET, Cookie, Server, JSON
  • ตรวจสอบความถูกต้องของข้อมูล (Validation)
  • ทำความสะอาดข้อมูล (Sanitization)
  • จัดการไฟล์อัปโหลดอย่างปลอดภัย
  • รองรับมาตรฐาน PSR-7 อย่างเต็มรูปแบบ

หมวดหมู่ Methods

  1. PSR-7 Methods - การจัดการ Request ตามมาตรฐาน PSR-7
  2. Get Methods - รับข้อมูลแบบต่างๆ
  3. Validation Methods - ตรวจสอบความถูกต้อง
  4. File Handling - จัดการไฟล์อัปโหลด
  5. JSON Methods - จัดการข้อมูล JSON
  6. Array Utilities - ยูทิลิตี้สำหรับ Array
  7. Error Handling - จัดการข้อผิดพลาด

1. PSR-7 Methods

__construct()

สร้าง Input instance

public function __construct(?ServerRequestInterface $request = null): void

พารามิเตอร์:

  • $request - PSR-7 Request object (ถ้าไม่ระบุจะสร้างใหม่อัตโนมัติ)

ตัวอย่าง:

use Kotchasan\Input;

// สร้างจาก request ปัจจุบัน
$input = new Input();

// สร้างจาก request ที่กำหนด
$customRequest = new Request();
$input = new Input($customRequest);

create()

สร้าง Input instance ด้วย static method

public static function create(?ServerRequestInterface $request = null): Input

คืนค่า: Input instance

ตัวอย่าง:

use Kotchasan\Input;

$input = Input::create();

getRequest()

ดึง PSR-7 Request object

public function getRequest(): ServerRequestInterface

คืนค่า: PSR-7 ServerRequestInterface

ตัวอย่าง:

$input = Input::create();
$request = $input->getRequest();

// ใช้ PSR-7 methods
$method = $request->getMethod();
$uri = $request->getUri();

withRequest()

สร้าง Input instance ใหม่ด้วย Request ที่เปลี่ยนแปลง (Immutable)

public function withRequest(ServerRequestInterface $request): Input

พารามิเตอร์:

  • $request - Request object ใหม่

คืนค่า: Input instance ใหม่

ตัวอย่าง:

$input = Input::create();

$newRequest = $input->getRequest()->withMethod('POST');
$newInput = $input->withRequest($newRequest);

// $input ยังคงเหมือนเดิม, $newInput มี request ใหม่

withQueryParams()

สร้าง Input instance ใหม่ด้วย Query parameters ที่เปลี่ยนแปลง

public function withQueryParams(array $query): Input

พารามิเตอร์:

  • $query - Query parameters ใหม่

คืนค่า: Input instance ใหม่

ตัวอย่าง:

$input = Input::create();

$newInput = $input->withQueryParams([
    'page' => 2,
    'limit' => 20
]);

$page = $newInput->getInt('page'); // 2

withParsedBody()

สร้าง Input instance ใหม่ด้วย Parsed body ที่เปลี่ยนแปลง

public function withParsedBody(array|object|null $data): Input

พารามิเตอร์:

  • $data - ข้อมูล body ใหม่

คืนค่า: Input instance ใหม่

ตัวอย่าง:

$input = Input::create();

$newInput = $input->withParsedBody([
    'username' => 'john',
    'email' => 'john@example.com'
]);

withCookieParams()

สร้าง Input instance ใหม่ด้วย Cookie parameters ที่เปลี่ยนแปลง

public function withCookieParams(array $cookies): Input

พารามิเตอร์:

  • $cookies - Cookie parameters ใหม่

คืนค่า: Input instance ใหม่

ตัวอย่าง:

$input = Input::create();

$newInput = $input->withCookieParams([
    'session_id' => 'abc123',
    'theme' => 'dark'
]);

withUploadedFiles()

สร้าง Input instance ใหม่ด้วย Uploaded files ที่เปลี่ยนแปลง

public function withUploadedFiles(array $uploadedFiles): Input

พารามิเตอร์:

  • $uploadedFiles - Uploaded files ใหม่

คืนค่า: Input instance ใหม่

ตัวอย่าง:

$input = Input::create();

$newInput = $input->withUploadedFiles([
    'avatar' => $uploadedFile
]);

2. Get Methods

get()

ดึงค่าจาก request

public function get(string $name, mixed $default = null, string $source = 'all'): mixed

พารามิเตอร์:

  • $name - ชื่อพารามิเตอร์
  • $default - ค่าเริ่มต้นถ้าไม่พบ
  • $source - แหล่งข้อมูล: 'post', 'get', 'cookie', 'server', 'json', 'all'

คืนค่า: ค่าของพารามิเตอร์ (InputItem หรือ Inputs สำหรับ fluent API)

ตัวอย่าง:

$input = Input::create();

// รับจาก POST หรือ GET
$username = $input->get('username');

// รับจาก POST เท่านั้น
$password = $input->get('password', '', 'post');

// รับจาก GET เท่านั้น
$page = $input->get('page', 1, 'get');

// รับจาก Cookie
$theme = $input->get('theme', 'light', 'cookie');

all()

ดึงข้อมูลทั้งหมดจากแหล่งที่ระบุ

public function all(string $source = 'all'): array

พารามิเตอร์:

  • $source - แหล่งข้อมูล

คืนค่า: array ของข้อมูลทั้งหมด

ตัวอย่าง:

$input = Input::create();

// ดึงข้อมูลทั้งหมด
$allData = $input->all();

// ดึงเฉพาะ POST
$postData = $input->all('post');

// ดึงเฉพาะ GET
$getData = $input->all('get');

// ดึง JSON data
$jsonData = $input->all('json');

getString()

ดึงข้อมูลแบบ string ที่ผ่านการทำความสะอาดแล้ว

public function getString(string $name, mixed $default = '', string $source = 'all'): string

พารามิเตอร์:

  • $name - ชื่อพารามิเตอร์
  • $default - ค่าเริ่มต้น
  • $source - แหล่งข้อมูล

คืนค่า: string ที่ถูก sanitize แล้ว

ตัวอย่าง:

$input = Input::create();

$name = $input->getString('name');
$bio = $input->getString('bio', 'No bio');

// ข้อมูลจะถูกลบ HTML tags, script tags, SQL injection patterns

getInt()

ดึงข้อมูลแบบ integer

public function getInt(string $name, int $default = 0, string $source = 'all'): int

พารามิเตอร์:

  • $name - ชื่อพารามิเตอร์
  • $default - ค่าเริ่มต้น
  • $source - แหล่งข้อมูล

คืนค่า: integer

ตัวอย่าง:

$input = Input::create();

$id = $input->getInt('id');
$page = $input->getInt('page', 1);
$limit = $input->getInt('limit', 10);

getFloat()

ดึงข้อมูลแบบ float

public function getFloat(string $name, float $default = 0.0, string $source = 'all'): float

พารามิเตอร์:

  • $name - ชื่อพารามิเตอร์
  • $default - ค่าเริ่มต้น
  • $source - แหล่งข้อมูล

คืนค่า: float

ตัวอย่าง:

$input = Input::create();

$price = $input->getFloat('price');
$rating = $input->getFloat('rating', 0.0);
$discount = $input->getFloat('discount');

getBool()

ดึงข้อมูลแบบ boolean

public function getBool(string $name, bool $default = false, string $source = 'all'): bool

พารามิเตอร์:

  • $name - ชื่อพารามิเตอร์
  • $default - ค่าเริ่มต้น
  • $source - แหล่งข้อมูล

คืนค่า: boolean

ตัวอย่าง:

$input = Input::create();

$agreed = $input->getBool('agree_terms');
$remember = $input->getBool('remember_me', false);
$isActive = $input->getBool('is_active');

// รองรับ: true, 1, '1', 'yes', 'on', 'true'

getArray()

ดึงข้อมูลแบบ array

public function getArray(string $name, array $default = [], string $source = 'all'): array

พารามิเตอร์:

  • $name - ชื่อพารามิเตอร์
  • $default - ค่าเริ่มต้น
  • $source - แหล่งข้อมูล

คืนค่า: array

ตัวอย่าง:

$input = Input::create();

$tags = $input->getArray('tags', []);
$categories = $input->getArray('categories');
$permissions = $input->getArray('permissions', ['read']);

getNestedArray()

ดึงข้อมูล array แบบซ้อนด้วย dot notation

public function getNestedArray(string $name, array $default = [], string $source = 'all'): array

พารามิเตอร์:

  • $name - ชื่อพารามิเตอร์ (รองรับ dot notation)
  • $default - ค่าเริ่มต้น
  • $source - แหล่งข้อมูล

คืนค่า: array

ตัวอย่าง:

$input = Input::create();

// ดึง $data['user']['address']['city']
$city = $input->getNestedArray('user.address.city');

// ดึง $data['config']['database']['connections']
$connections = $input->getNestedArray('config.database.connections', []);

getDate()

ดึงข้อมูลแบบวันที่

public function getDate(string $name, string $default = '', string $source = 'all'): string

พารามิเตอร์:

  • $name - ชื่อพารามิเตอร์
  • $default - ค่าเริ่มต้น
  • $source - แหล่งข้อมูล

คืนค่า: string (รูปแบบวันที่ที่ถูกต้อง หรือ default)

ตัวอย่าง:

$input = Input::create();

$birthDate = $input->getDate('birth_date');
$startDate = $input->getDate('start_date', date('Y-m-d'));

// ต้องเป็นรูปแบบวันที่ที่ถูกต้อง (Y-m-d)

getTime()

ดึงข้อมูลแบบเวลา

public function getTime(string $name, string $default = '', string $source = 'all'): string

พารามิเตอร์:

  • $name - ชื่อพารามิเตอร์
  • $default - ค่าเริ่มต้น
  • $source - แหล่งข้อมูล

คืนค่า: string (รูปแบบเวลาที่ถูกต้อง หรือ default)

ตัวอย่าง:

$input = Input::create();

$meetingTime = $input->getTime('meeting_time');
$startTime = $input->getTime('start_time', '09:00');

// ต้องเป็นรูปแบบเวลาที่ถูกต้อง (H:i:s หรือ H:i)

getEmail()

ดึงข้อมูลแบบอีเมล

public function getEmail(string $name, string $default = '', string $source = 'all'): string

พารามิเตอร์:

  • $name - ชื่อพารามิเตอร์
  • $default - ค่าเริ่มต้น
  • $source - แหล่งข้อมูล

คืนค่า: string (อีเมลที่ถูกต้อง หรือ default)

ตัวอย่าง:

$input = Input::create();

$email = $input->getEmail('email');
$recoveryEmail = $input->getEmail('recovery_email', '');

// ตรวจสอบ format อีเมล

getUrl()

ดึงข้อมูลแบบ URL

public function getUrl(string $name, string $default = '', string $source = 'all'): string

พารามิเตอร์:

  • $name - ชื่อพารามิเตอร์
  • $default - ค่าเริ่มต้น
  • $source - แหล่งข้อมูล

คืนค่า: string (URL ที่ถูกต้อง หรือ default)

ตัวอย่าง:

$input = Input::create();

$website = $input->getUrl('website');
$profileUrl = $input->getUrl('profile_url', '');

// ตรวจสอบ format URL

getPhone()

ดึงข้อมูลแบบเบอร์โทรศัพท์

public function getPhone(string $name, string $default = '', string $source = 'all'): string

พารามิเตอร์:

  • $name - ชื่อพารามิเตอร์
  • $default - ค่าเริ่มต้น
  • $source - แหล่งข้อมูล

คืนค่า: string (เบอร์โทรที่ถูกต้อง หรือ default)

ตัวอย่าง:

$input = Input::create();

$phone = $input->getPhone('phone');
$mobile = $input->getPhone('mobile', '');

// ตรวจสอบ format เบอร์โทร

getUsername()

ดึงข้อมูลแบบ username

public function getUsername(string $name, string $default = '', string $source = 'all'): string

พารามิเตอร์:

  • $name - ชื่อพารามิเตอร์
  • $default - ค่าเริ่มต้น
  • $source - แหล่งข้อมูล

คืนค่า: string (username ที่ถูกต้อง หรือ default)

ตัวอย่าง:

$input = Input::create();

$username = $input->getUsername('username');

// ตรวจสอบ format username (อักษร, ตัวเลข, _, -)

getValidatedArray()

ดึง array ที่ผ่านการตรวจสอบตาม schema

public function getValidatedArray(string $name, array $schema, array $default = [], string $source = 'all'): array

พารามิเตอร์:

  • $name - ชื่อพารามิเตอร์
  • $schema - Schema สำหรับตรวจสอบ
  • $default - ค่าเริ่มต้น
  • $source - แหล่งข้อมูล

คืนค่า: array ที่ผ่านการตรวจสอบ

ตัวอย่าง:

$input = Input::create();

$schema = [
    'name' => 'string',
    'age' => 'integer',
    'email' => 'email'
];

$userData = $input->getValidatedArray('user', $schema, []);

3. Validation Methods

rules()

กำหนด validation rules

public function rules(array $rules): Input

พารามิเตอร์:

  • $rules - array ของ validation rules

คืนค่า: $this (สำหรับ method chaining)

ตัวอย่าง:

$input = Input::create();

$input->rules([
    'username' => [
        'required' => 'Username is required',
        'min' => ['value' => 3, 'message' => 'Username must be at least 3 characters'],
        'max' => 20,
        'pattern' => '/^[a-zA-Z0-9_]+$/',
        'label' => 'Username'
    ],
    'email' => [
        'required' => 'Email is required',
        'email' => 'Invalid email format',
        'label' => 'Email Address'
    ],
    'password' => [
        'required' => 'Password is required',
        'min' => 8,
        'password' => 8
    ]
]);

validate()

ตรวจสอบข้อมูลตาม rules ที่กำหนด

public function validate(?array $data = null): bool

พารามิเตอร์:

  • $data - ข้อมูลที่จะตรวจสอบ (ถ้าไม่ระบุจะใช้ข้อมูลจาก request)

คืนค่า: true ถ้าผ่าน, false ถ้าไม่ผ่าน

ตัวอย่าง:

$input = Input::create();

$input->rules([
    'email' => ['required' => true, 'email' => true],
    'age' => ['integer' => true, 'between' => [18, 100]]
]);

if ($input->validate()) {
    $validData = $input->validated();
    // บันทึกข้อมูล
} else {
    $errors = $input->errors();
    // แสดง errors
}

errors()

ดึง validation errors ทั้งหมด

public function errors(): array

คืนค่า: array ของ error messages

ตัวอย่าง:

$input = Input::create();

$input->rules([
    'name' => ['required' => 'Name required'],
    'email' => ['required' => 'Email required', 'email' => 'Invalid email']
]);

if (!$input->validate()) {
    $errors = $input->errors();
    /*
    [
        'name' => 'Name required',
        'email' => 'Invalid email'
    ]
    */
}

firstError()

ดึง error แรก

public function firstError(): ?string

คืนค่า: error message แรก หรือ null

ตัวอย่าง:

$input = Input::create();

if (!$input->validate()) {
    $firstError = $input->firstError();
    echo $firstError; // แสดง error แรก
}

validated()

ดึงข้อมูลที่ผ่านการตรวจสอบ

public function validated(): array

คืนค่า: array ของข้อมูลที่ผ่าน validation

Throws: RuntimeException ถ้ายังไม่ได้ validate หรือ validation ไม่ผ่าน

ตัวอย่าง:

$input = Input::create();

$input->rules([
    'name' => ['required' => true],
    'email' => ['required' => true, 'email' => true],
    'age' => ['integer' => true]
]);

if ($input->validate()) {
    $data = $input->validated();
    // มีเฉพาะ fields ที่อยู่ใน rules
}

addCustomRule()

เพิ่ม custom validation rule

public function addCustomRule(string $name, callable $callback, string $errorMessage = ''): Input

พารามิเตอร์:

  • $name - ชื่อ rule
  • $callback - callback function สำหรับตรวจสอบ
  • $errorMessage - error message เริ่มต้น

คืนค่า: $this

ตัวอย่าง:

$input = Input::create();

// เพิ่ม custom rule
$input->addCustomRule('phone_th', function($value) {
    return preg_match('/^0[0-9]{9}$/', $value);
}, 'Invalid Thai phone number');

// ใช้ custom rule
$input->rules([
    'phone' => [
        'required' => true,
        'phone_th' => true
    ]
]);

getCustomRules()

ดึง custom rules ทั้งหมด

public function getCustomRules(): array

คืนค่า: array ของ custom rules

ตัวอย่าง:

$input = Input::create();

$input->addCustomRule('uppercase', function($value) {
    return $value === strtoupper($value);
}, 'Must be uppercase');

$rules = $input->getCustomRules();

getGroupedErrors()

ดึง errors แบบจัดกลุ่ม

public function getGroupedErrors(): array

คืนค่า: array ของ errors จัดกลุ่มตาม group

ตัวอย่าง:

$input = Input::create();

$input->rules([
    'email' => [
        'required' => true,
        'email' => true,
        'group' => 'personal',
        'label' => 'Email'
    ],
    'phone' => [
        'required' => true,
        'group' => 'personal',
        'label' => 'Phone'
    ],
    'company' => [
        'required' => true,
        'group' => 'business',
        'label' => 'Company'
    ]
]);

if (!$input->validate()) {
    $grouped = $input->getGroupedErrors();
    /*
    [
        'personal' => ['email' => '...', 'phone' => '...'],
        'business' => ['company' => '...']
    ]
    */
}

getErrorsForGroup()

ดึง errors สำหรับ group ที่ระบุ

public function getErrorsForGroup(string $group): array

พารามิเตอร์:

  • $group - ชื่อ group

คืนค่า: array ของ errors

ตัวอย่าง:

$input = Input::create();

if (!$input->validate()) {
    $personalErrors = $input->getErrorsForGroup('personal');
}

getFormattedErrors()

ดึง errors ที่ format แล้ว

public function getFormattedErrors(): array

คืนค่า: array ของ formatted error messages

ตัวอย่าง:

$input = Input::create();

$input->rules([
    'email' => [
        'required' => ':attribute is required',
        'label' => 'Email Address'
    ]
]);

if (!$input->validate()) {
    $errors = $input->getFormattedErrors();
    // 'email' => 'Email Address is required'
}

4. File Handling Methods

getFile()

ดึงไฟล์อัปโหลด

public function getFile(string $name): ?array

พารามิเตอร์:

  • $name - ชื่อ input field

คืนค่า: array ของข้อมูลไฟล์ หรือ null

ตัวอย่าง:

$input = Input::create();

$file = $input->getFile('avatar');

if ($file && $file['error'] === UPLOAD_ERR_OK) {
    $filename = $file['name'];
    $tmpPath = $file['tmp_name'];
    $size = $file['size'];
    $type = $file['type'];
}

getImage()

ดึงไฟล์รูปภาพพร้อมตรวจสอบ

public function getImage(string $name, array $allowedTypes = ['jpg', 'jpeg', 'png', 'gif'], int $maxWidth = 0, int $maxHeight = 0): ?array

พารามิเตอร์:

  • $name - ชื่อ input field
  • $allowedTypes - นามสกุลที่อนุญาต
  • $maxWidth - ความกว้างสูงสุด (0 = ไม่จำกัด)
  • $maxHeight - ความสูงสูงสุด (0 = ไม่จำกัด)

คืนค่า: array ของข้อมูลรูปภาพ หรือ null

ตัวอย่าง:

$input = Input::create();

// รูปภาพทั่วไป
$avatar = $input->getImage('avatar');

// จำกัดเฉพาะ PNG
$logo = $input->getImage('logo', ['png']);

// จำกัดขนาด
$banner = $input->getImage('banner', ['jpg', 'png'], 1920, 1080);

if ($avatar) {
    // ตรวจสอบแล้วว่าเป็นรูปภาพจริง
    move_uploaded_file($avatar['tmp_name'], 'uploads/' . $avatar['name']);
}

getSecureFile()

ดึงไฟล์พร้อมตรวจสอบความปลอดภัย

public function getSecureFile(string $name, array $allowedTypes = [], array $allowedMimes = [], int $maxSize = 0): ?array

พารามิเตอร์:

  • $name - ชื่อ input field
  • $allowedTypes - นามสกุลที่อนุญาต
  • $allowedMimes - MIME types ที่อนุญาต
  • $maxSize - ขนาดสูงสุด (bytes, 0 = ไม่จำกัด)

คืนค่า: array ของข้อมูลไฟล์ หรือ null

ตัวอย่าง:

$input = Input::create();

// PDF เท่านั้น, ไม่เกิน 5MB
$document = $input->getSecureFile(
    'document',
    ['pdf'],
    ['application/pdf'],
    5 * 1024 * 1024
);

if ($document) {
    // ผ่านการตรวจสอบความปลอดภัยแล้ว
    // มี $document['real_mime'] เพิ่มเติม
}

isFileSafe()

ตรวจสอบว่าไฟล์ปลอดภัย

public function isFileSafe(string $name): bool

พารามิเตอร์:

  • $name - ชื่อ input field

คืนค่า: true ถ้าปลอดภัย

ตัวอย่าง:

$input = Input::create();

if ($input->isFileSafe('document')) {
    $file = $input->getFile('document');
    // ไฟล์ไม่มีโค้ดอันตราย
}

isExtensionMatchingMimeType()

ตรวจสอบว่านามสกุลตรงกับ MIME type

public function isExtensionMatchingMimeType(string $name): bool

พารามิเตอร์:

  • $name - ชื่อ input field

คืนค่า: true ถ้าตรงกัน

ตัวอย่าง:

$input = Input::create();

if (!$input->isExtensionMatchingMimeType('avatar')) {
    // ไฟล์ .jpg แต่เป็น PNG จริงๆ (ปลอมนามสกุล)
    throw new Exception('File extension does not match content');
}

getUploadedFilePath()

ดึง path ของไฟล์อัปโหลด (private method)

private function getUploadedFilePath(UploadedFileInterface $file): string

5. JSON Methods

getJson()

ดึงข้อมูล JSON จาก request body

public function getJson(): ?array

คืนค่า: array ของข้อมูล JSON หรือ null

ตัวอย่าง:

$input = Input::create();

// POST /api/users
// Content-Type: application/json
// Body: {"name": "John", "email": "john@example.com"}

$json = $input->getJson();
/*
[
    'name' => 'John',
    'email' => 'john@example.com'
]
*/

getJsonData()

ดึงค่าจาก JSON data

public function getJsonData(string $name, mixed $default = null): mixed

พารามิเตอร์:

  • $name - ชื่อ field (รองรับ dot notation)
  • $default - ค่าเริ่มต้น

คืนค่า: ค่าของ field

ตัวอย่าง:

$input = Input::create();

// JSON: {"user": {"name": "John", "address": {"city": "Bangkok"}}}

$name = $input->getJsonData('user.name'); // "John"
$city = $input->getJsonData('user.address.city'); // "Bangkok"
$unknown = $input->getJsonData('user.age', 0); // 0

isJson()

ตรวจสอบว่า request เป็น JSON

public function isJson(): bool

คืนค่า: true ถ้าเป็น JSON request

ตัวอย่าง:

$input = Input::create();

if ($input->isJson()) {
    $data = $input->getJson();
    // จัดการข้อมูล JSON
} else {
    // จัดการข้อมูล form
}

6. Array Utilities

filterArrayKeys()

กรองเฉพาะ keys ที่ต้องการ

public function filterArrayKeys(array $array, array $keys): array

พารามิเตอร์:

  • $array - array ต้นทาง
  • $keys - keys ที่จะเก็บ

คืนค่า: array ที่ถูกกรอง

ตัวอย่าง:

$input = Input::create();

$data = [
    'name' => 'John',
    'email' => 'john@example.com',
    'password' => 'secret',
    'age' => 30
];

$filtered = $input->filterArrayKeys($data, ['name', 'email']);
// ['name' => 'John', 'email' => 'john@example.com']

filterArray()

กรอง array ด้วย callback

public function filterArray(array $array, callable $callback): array

พารามิเตอร์:

  • $array - array ต้นทาง
  • $callback - callback function

คืนค่า: array ที่ถูกกรอง

ตัวอย่าง:

$input = Input::create();

$numbers = [1, 2, 3, 4, 5, 6];

$even = $input->filterArray($numbers, function($n) {
    return $n % 2 === 0;
});
// [2, 4, 6]

mapArray()

แปลง array ด้วย callback

public function mapArray(array $array, callable $callback): array

พารามิเตอร์:

  • $array - array ต้นทาง
  • $callback - callback function

คืนค่า: array ที่ถูกแปลง

ตัวอย่าง:

$input = Input::create();

$numbers = [1, 2, 3, 4, 5];

$doubled = $input->mapArray($numbers, function($n) {
    return $n * 2;
});
// [2, 4, 6, 8, 10]

validateArrayElements()

ตรวจสอบแต่ละ element ใน array

public function validateArrayElements(string $name, array $rules, array $default = [], string $source = 'all'): array

พารามิเตอร์:

  • $name - ชื่อพารามิเตอร์
  • $rules - validation rules สำหรับแต่ละ element
  • $default - ค่าเริ่มต้น
  • $source - แหล่งข้อมูล

คืนค่า: array ที่ผ่าน validation

ตัวอย่าง:

$input = Input::create();

// POST emails[]=john@test.com&emails[]=invalid&emails[]=jane@test.com

$validEmails = $input->validateArrayElements('emails', [
    'email' => true,
    'sanitize' => true
], []);

// ['john@test.com', 'jane@test.com']

validateNestedArray()

ตรวจสอบ nested array ด้วย dot notation

public function validateNestedArray(string $name, array $rules, array $default = [], string $source = 'all'): array

พารามิเตอร์:

  • $name - ชื่อพารามิเตอร์
  • $rules - validation rules (dot notation)
  • $default - ค่าเริ่มต้น
  • $source - แหล่งข้อมูล

คืนค่า: array ที่ผ่าน validation

ตัวอย่าง:

$input = Input::create();

$rules = [
    'user.name' => ['required' => true, 'sanitize' => true],
    'user.email' => ['required' => true, 'email' => true],
    'user.age' => ['integer' => true, 'min' => 18]
];

$validData = $input->validateNestedArray('data', $rules, []);

sanitizeArray()

ทำความสะอาด array แบบ recursive

public function sanitizeArray(array $array): array

พารามิเตอร์:

  • $array - array ที่จะทำความสะอาด

คืนค่า: array ที่สะอาดแล้ว

ตัวอย่าง:

$input = Input::create();

$data = [
    'name' => '<script>alert("XSS")</script>John',
    'bio' => 'Hello <b>World</b>',
    'nested' => [
        'field' => 'DROP TABLE users'
    ]
];

$clean = $input->sanitizeArray($data);
// ลบ script tags, HTML tags, SQL patterns ทั้งหมด

dot()

แปลง array เป็น flat array ด้วย dot notation

public function dot(array $array, string $prepend = ''): array

พารามิเตอร์:

  • $array - array ที่จะ flatten
  • $prepend - prefix สำหรับ keys

คืนค่า: flattened array

ตัวอย่าง:

$input = Input::create();

$data = [
    'user' => [
        'name' => 'John',
        'address' => [
            'city' => 'Bangkok',
            'country' => 'Thailand'
        ]
    ]
];

$flattened = $input->dot($data);
/*
[
    'user.name' => 'John',
    'user.address.city' => 'Bangkok',
    'user.address.country' => 'Thailand'
]
*/

getValueByPath()

ดึงค่าจาก nested array ด้วย dot notation

public function getValueByPath(array $array, string $path, mixed $default = null): mixed

พารามิเตอร์:

  • $array - array ต้นทาง
  • $path - path แบบ dot notation
  • $default - ค่าเริ่มต้น

คืนค่า: ค่าที่ path หรือ default

ตัวอย่าง:

$input = Input::create();

$data = [
    'user' => [
        'profile' => [
            'name' => 'John'
        ]
    ]
];

$name = $input->getValueByPath($data, 'user.profile.name'); // "John"
$age = $input->getValueByPath($data, 'user.age', 0); // 0

setValueByPath()

ตั้งค่าใน nested array ด้วย dot notation

public function setValueByPath(array &$array, string $path, mixed $value): void

พารามิเตอร์:

  • $array - array (ส่งแบบ reference)
  • $path - path แบบ dot notation
  • $value - ค่าที่จะตั้ง

ตัวอย่าง:

$input = Input::create();

$data = [];

$input->setValueByPath($data, 'user.profile.name', 'John');
$input->setValueByPath($data, 'user.profile.email', 'john@example.com');

/*
$data = [
    'user' => [
        'profile' => [
            'name' => 'John',
            'email' => 'john@example.com'
        ]
    ]
]
*/

7. Error Handling & Utilities

sanitize()

ทำความสะอาด string

public function sanitize(string $value): string

พารามิเตอร์:

  • $value - string ที่จะทำความสะอาด

คืนค่า: string ที่สะอาดแล้ว

ตัวอย่าง:

$input = Input::create();

$dirty = '<script>alert("XSS")</script>Hello';
$clean = $input->sanitize($dirty); // "Hello"

// ลบ:
// - HTML tags
// - Script tags
// - SQL injection patterns
// - Path traversal
// - Null bytes

getFirstGroupErrors()

ดึง error แรกจากแต่ละ group

public function getFirstGroupErrors(): array

คืนค่า: array ของ first error ในแต่ละ group

ตัวอย่าง:

$input = Input::create();

if (!$input->validate()) {
    $firstErrors = $input->getFirstGroupErrors();
    /*
    [
        'personal' => 'Email is required',
        'business' => 'Company name is required'
    ]
    */
}

errorsToHtml()

แปลง errors เป็น HTML list

public function errorsToHtml(string $listType = 'ul', array $attributes = []): string

พารามิเตอร์:

  • $listType - 'ul' หรือ 'ol'
  • $attributes - HTML attributes

คืนค่า: HTML string

ตัวอย่าง:

$input = Input::create();

if (!$input->validate()) {
    // Unordered list
    echo $input->errorsToHtml();

    // Ordered list with class
    echo $input->errorsToHtml('ol', ['class' => 'error-list']);

    /*
    <ul>
        <li>Email is required</li>
        <li>Password must be at least 8 characters</li>
    </ul>
    */
}

evaluateConditionalRules()

ประเมิน conditional validation rules (protected method)

protected function evaluateConditionalRules(string $field, array $rules): bool

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

1. Form Validation แบบสมบูรณ์

use Kotchasan\Input;

$input = Input::create();

// กำหนด rules
$input->rules([
    'username' => [
        'required' => 'Username is required',
        'min' => ['value' => 3, 'message' => 'Username must be at least 3 characters'],
        'max' => 20,
        'pattern' => '/^[a-zA-Z0-9_]+$/',
        'label' => 'Username'
    ],
    'email' => [
        'required' => 'Email is required',
        'email' => 'Invalid email format',
        'label' => 'Email Address'
    ],
    'password' => [
        'required' => 'Password is required',
        'min' => 8,
        'password' => 8,
        'label' => 'Password'
    ],
    'password_confirm' => [
        'required' => 'Please confirm password',
        'same_as' => 'password',
        'label' => 'Password Confirmation'
    ],
    'age' => [
        'integer' => 'Age must be a number',
        'between' => [18, 100],
        'label' => 'Age'
    ],
    'agree_terms' => [
        'required' => 'You must agree to terms',
        'label' => 'Terms Agreement'
    ]
]);

// ตรวจสอบ
if ($input->validate()) {
    $data = $input->validated();

    // บันทึกข้อมูล
    // ...

    echo "Registration successful!";
} else {
    // แสดง errors
    echo $input->errorsToHtml('ul', ['class' => 'errors']);
}

2. File Upload พร้อม Validation

use Kotchasan\Input;
use Kotchasan\Image;

$input = Input::create();

// อัปโหลดรูปภาพ
$avatar = $input->getImage('avatar', ['jpg', 'jpeg', 'png'], 800, 800);

if ($avatar) {
    // Resize และบันทึก
    $result = Image::resize(
        $avatar['tmp_name'],
        'uploads/avatars/',
        'avatar_' . uniqid() . '.jpg',
        400
    );

    echo "Avatar uploaded successfully!";
} else {
    echo "Please upload a valid image (JPG/PNG, max 800x800)";
}

// อัปโหลดเอกสาร
$document = $input->getSecureFile(
    'document',
    ['pdf', 'doc', 'docx'],
    ['application/pdf', 'application/msword'],
    10 * 1024 * 1024 // 10MB
);

if ($document && $input->isFileSafe('document')) {
    move_uploaded_file(
        $document['tmp_name'],
        'uploads/documents/' . basename($document['name'])
    );
}

3. API Endpoint รับ JSON

use Kotchasan\Input;

$input = Input::create();

if ($input->isJson()) {
    $data = $input->getJson();

    // ตรวจสอบ
    $input->rules([
        'name' => ['required' => 'Name is required'],
        'email' => ['required' => 'Email is required', 'email' => 'Invalid email']
    ]);

    if ($input->validate($data)) {
        $validData = $input->validated();

        // ประมวลผล
        // ...

        header('Content-Type: application/json');
        echo json_encode(['success' => true, 'data' => $validData]);
    } else {
        header('Content-Type: application/json', true, 400);
        echo json_encode(['success' => false, 'errors' => $input->errors()]);
    }
} else {
    header('Content-Type: application/json', true, 400);
    echo json_encode(['success' => false, 'message' => 'JSON data expected']);
}

4. Custom Validation Rules

use Kotchasan\Input;

$input = Input::create();

// เพิ่ม custom rules
$input->addCustomRule('phone_th', function($value) {
    return preg_match('/^0[0-9]{9}$/', $value);
}, 'Invalid Thai phone number format');

$input->addCustomRule('citizen_id', function($value) {
    if (!preg_match('/^[0-9]{13}$/', $value)) {
        return false;
    }

    // ตรวจสอบ check digit
    $sum = 0;
    for ($i = 0; $i < 12; $i++) {
        $sum += (int)$value[$i] * (13 - $i);
    }
    $checkDigit = (11 - ($sum % 11)) % 10;

    return $checkDigit == (int)$value[12];
}, 'Invalid Thai citizen ID');

// ใช้งาน
$input->rules([
    'phone' => ['required' => true, 'phone_th' => true],
    'citizen_id' => ['required' => true, 'citizen_id' => true]
]);

if ($input->validate()) {
    echo "Validation passed!";
}

5. Conditional Validation

use Kotchasan\Input;

$input = Input::create();

$input->rules([
    'payment_method' => [
        'required' => 'Please select payment method',
        'in' => ['credit_card', 'paypal', 'bank_transfer']
    ],
    'card_number' => [
        'when' => [
            'field' => 'payment_method',
            'value' => 'credit_card',
            'operator' => '=='
        ],
        'required' => 'Card number is required for credit card',
        'pattern' => '/^[0-9]{16}$/'
    ],
    'paypal_email' => [
        'when' => [
            'field' => 'payment_method',
            'value' => 'paypal'
        ],
        'required' => 'PayPal email required',
        'email' => 'Invalid email'
    ]
]);

// Validation จะเช็คเฉพาะ fields ที่เงื่อนไขตรง
if ($input->validate()) {
    $data = $input->validated();
}

6. Array Data Validation

use Kotchasan\Input;$input = Input::create();

// ตรวจสอบ array ของอีเมล
$validEmails = $input->validateArrayElements('emails', [
    'email' => true,
    'sanitize' => true
], []);

// ตรวจสอบ nested data
$rules = [
    'items.*.name' => ['required' => true, 'sanitize' => true],
    'items.*.quantity' => ['required' => true, 'integer' => true, 'min' => 1],
    'items.*.price' => ['required' => true, 'float' => true, 'min' => 0]
];

$validatedData = $input->validateNestedArray('order', $rules, []);

Best Practices

1. ความปลอดภัย (Security)

// ✅ ดี: ใช้ validation และ sanitization
$name = $input->getString('name');
$email = $input->getEmail('email');

// ❌ ไม่ดี: ใช้ข้อมูลโดยตรง
$name = $_POST['name']; // อันตราย!

2. Type Safety

// ✅ ดี: ใช้ typed getters
$id = $input->getInt('id');
$price = $input->getFloat('price');
$active = $input->getBool('active');

// ❌ ไม่ดี: ใช้ get() แล้ว cast เอง
$id = (int) $input->get('id');

3. File Upload Security

// ✅ ดี: ตรวจสอบความปลอดภัย
$file = $input->getSecureFile('upload', ['pdf'], [], 5*1024*1024);
if ($file && $input->isFileSafe('upload')) {
    // ปลอดภัย
}

// ❌ ไม่ดี: ไม่ตรวจสอบ
$file = $_FILES['upload'];
move_uploaded_file($file['tmp_name'], 'uploads/' . $file['name']);

4. Validation Best Practices

// ✅ ดี: ใช้ labels และ custom messages
$input->rules([
    'email' => [
        'required' => 'กรุณากรอกอีเมล',
        'email' => 'รูปแบบอีเมลไม่ถูกต้อง',
        'label' => 'อีเมล'
    ]
]);

// ✅ ดี: Group related validations
$input->rules([
    'first_name' => ['required' => true, 'group' => 'personal'],
    'last_name' => ['required' => true, 'group' => 'personal'],
    'company' => ['required' => true, 'group' => 'business']
]);

5. Error Handling

// ✅ ดี: แสดง errors อย่างเหมาะสม
if (!$input->validate()) {
    $errors = $input->getGroupedErrors();
    foreach ($errors as $group => $groupErrors) {
        echo "<h3>{$group}</h3>";
        foreach ($groupErrors as $field => $error) {
            echo "<p>{$error}</p>";
        }
    }
}

// ✅ ดี: ส่ง JSON errors
if (!$input->validate()) {
    http_response_code(400);
    echo json_encode([
        'success' => false,
        'errors' => $input->errors(),
        'first_error' => $input->firstError()
    ]);
    exit;
}

สรุป

คลาส Input เป็นเครื่องมือที่ทรงพลังสำหรับ:

  • ✅ รับข้อมูลจากหลายแหล่งอย่างปลอดภัย
  • ✅ ตรวจสอบความถูกต้องด้วย validation rules ที่ยืดหยุ่น
  • ✅ ทำความสะอาดข้อมูลอัตโนมัติ
  • ✅ จัดการไฟล์อัปโหลดอย่างปลอดภัย
  • ✅ รองรับมาตรฐาน PSR-7
  • ✅ จัดการ JSON data ได้สะดวก
  • ✅ Immutable pattern สำหรับ PSR-7

การใช้งาน Input class อย่างถูกต้องช่วยป้องกัน:

  • XSS (Cross-Site Scripting)
  • SQL Injection
  • File Upload Vulnerabilities
  • Type Confusion Attacks
  • Path Traversal

จำนวน Methods: 57 methods
ขนาดไฟล์: 1,667 บรรทัด
หมวดหมู่: 7 หมวด