Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> PHP

รวม filter_input() Flags ด้วย AND/OR ใน PHP

filter_input() รองรับ Flags ผ่าน Bitwise OR (|) ไม่ใช่ Logical AND/OR ทั่วไป

Flags ที่ใช้ร่วมกันได้ (Bitwise OR)

$value = filter_input(INPUT_POST, 'field', FILTER_DEFAULT, 
    FILTER_REQUIRE_ARRAY | FILTER_NULL_ON_FAILURE
);

Flags หลักของ filter_input

Flagคำอธิบาย
FILTER_REQUIRE_ARRAYบังคับให้ Input เป็น Array (เช่น name="field[]")
FILTER_FORCE_ARRAYถ้า Input ไม่ใช่ Array ให้ห่อใน Array (['value'])
FILTER_NULL_ON_FAILUREคืนค่า null แทน false เมื่อ Validation Fail
FILTER_REQUIRE_SCALARบังคับให้เป็น Scalar (ไม่ใช่ Array)

ตัวอย่าง: จัดการ Array และ Scalar พร้อมกัน

// POST: field_single=value, field_multi[]=a, field_multi[]=b

// Single Value
$single = filter_input(INPUT_POST, 'field_single', FILTER_SANITIZE_STRING);

// Array Value (ต้องใช้ FILTER_REQUIRE_ARRAY)
$multi = filter_input(INPUT_POST, 'field_multi', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY);
// Result: ['a', 'b']

// ทั้งคู่: ใช้ Loop แทน (เนื่องจาก Filter ต้องรู้ Type ก่อน)
$clean = [];
foreach ($_POST as $key => $value) {
    if (is_array($value)) {
        // Array Input
        $clean[$key] = filter_var_array($value, [
            '*' => FILTER_SANITIZE_STRING, // Filter ทุก Element
        ]);
    } else {
        // Scalar Input
        $clean[$key] = filter_input(INPUT_POST, $key, FILTER_SANITIZE_STRING);
    }
}

filter_var_array() - Filter หลายค่าพร้อมกัน (แนะนำ)

$args = [
    'name'     => FILTER_SANITIZE_STRING,
    'email'    => FILTER_VALIDATE_EMAIL,
    'age'      => ['filter' => FILTER_VALIDATE_INT, 'options' => ['min_range' => 1, 'max_range' => 120]],
    'tags'     => ['filter' => FILTER_DEFAULT, 'flags' => FILTER_REQUIRE_ARRAY], // Array
    'active'   => FILTER_VALIDATE_BOOLEAN,
];

$clean = filter_var_array($_POST, $args);

/* ผลลัพธ์:
[
    'name'   => 'John Doe',
    'email'  => 'john@example.com', // false ถ้า Invalid
    'age'    => 25,                  // false ถ้าไม่ใช่ Int หรือ Out of Range
    'tags'   => ['php', 'mysql'],    // Array
    'active' => true,                // true/false/null
]
*/

Custom Filter Function (PHP 8.1+)

$clean = filter_var_array($_POST, [
    'username' => function($value) {
        return preg_match('/^[a-zA-Z0-9_]{3,20}$/', $value) ? $value : false;
    },
    'tags' => ['filter' => FILTER_DEFAULT, 'flags' => FILTER_REQUIRE_ARRAY],
]);

⚠️ ข้อผิดพลาดที่พบบ่อย

// ❌ ผิด: ใช้ Logical OR (||) กับ Flags
$flags = FILTER_REQUIRE_ARRAY || FILTER_NULL_ON_FAILURE; // ผลลัพธ์เป็น Boolean (true/1)

// ✅ ถูก: ใช้ Bitwise OR (|)
$flags = FILTER_REQUIRE_ARRAY | FILTER_NULL_ON_FAILURE; // ผลลัพธ์เป็น Integer Bitmask

Best Practice: Whitelist Input Fields

function filterInput(array $whitelist): array {
    $args = [];
    foreach ($whitelist as $field => $filter) {
        if (is_array($filter)) {
            $args[$field] = $filter;
        } else {
            $args[$field] = ['filter' => $filter];
        }
    }
    
    // FILTER_NULL_ON_FAILURE: คืน null แทน false สำหรับ Missing/Invalid
    return filter_var_array($_POST, $args, true); // true = add FILTER_NULL_ON_FAILURE globally
}

// ใช้งาน
$whitelist = [
    'email'    => FILTER_VALIDATE_EMAIL,
    'name'     => FILTER_SANITIZE_STRING,
    'age'      => ['filter' => FILTER_VALIDATE_INT, 'options' => ['min_range' => 18]],
    'tags'     => ['filter' => FILTER_DEFAULT, 'flags' => FILTER_REQUIRE_ARRAY],
    'newsletter' => FILTER_VALIDATE_BOOLEAN,
];

$input = filterInput($whitelist);
// $input['email'] = 'john@example.com' หรือ null (ถ้า Invalid/Missing)