ตัวตรวจสอบอื่นๆ

มีตัวตรวจสอบหลายตัวใน composer ที่สามารถใช้งานได้โดยตรง เช่น:

webman/validation (แนะนำ)

top-think/think-validate

respect/validation

ตัวตรวจสอบ webman/validation

อิงจาก illuminate/validation รองรับการตรวจสอบแบบแมนนวล การตรวจสอบด้วย annotation การตรวจสอบระดับพารามิเตอร์ และชุดกฎที่นำกลับมาใช้ได้

การติดตั้ง

composer require webman/validation

แนวคิดพื้นฐาน

  • การใช้ชุดกฎซ้ำ: กำหนด rules, messages, attributes และ scenes ที่นำกลับมาใช้ได้โดยสืบทอดจาก support\validation\Validator สามารถใช้ซ้ำได้ทั้งการตรวจสอบแบบแมนนวลและ annotation
  • การตรวจสอบด้วย Annotation (Attribute) ระดับเมธอด: ใช้ PHP 8 attribute #[Validate] เพื่อผูกการตรวจสอบกับเมธอดของ controller
  • การตรวจสอบด้วย Annotation (Attribute) ระดับพารามิเตอร์: ใช้ PHP 8 attribute #[Param] เพื่อผูกการตรวจสอบกับพารามิเตอร์ของเมธอด controller
  • การจัดการข้อยกเว้น: โยน support\validation\ValidationException เมื่อการตรวจสอบล้มเหลว คลาสข้อยกเว้นสามารถกำหนดค่าได้
  • การตรวจสอบฐานข้อมูล: หากมีการตรวจสอบฐานข้อมูล ต้องติดตั้ง composer require webman/database

การตรวจสอบแบบแมนนวล

การใช้งานพื้นฐาน

use support\validation\Validator;

$data = ['email' => 'user@example.com'];

Validator::make($data, [
    'email' => 'required|email',
])->validate();

หมายเหตุ
validate() จะโยน support\validation\ValidationException เมื่อการตรวจสอบล้มเหลว หากไม่ต้องการให้โยนข้อยกเว้น ให้ใช้วิธี fails() ด้านล่างเพื่อรับข้อความข้อผิดพลาด

ข้อความและ attributes ที่กำหนดเอง

use support\validation\Validator;

$data = ['contact' => 'user@example.com'];

Validator::make(
    $data,
    ['contact' => 'required|email'],
    ['contact.email' => 'Invalid email format'],
    ['contact' => 'Email']
)->validate();

การตรวจสอบโดยไม่โยนข้อยกเว้น (รับข้อความข้อผิดพลาด)

หากไม่ต้องการให้โยนข้อยกเว้น ให้ใช้ fails() เพื่อตรวจสอบและรับข้อความข้อผิดพลาดผ่าน errors() (คืนค่า MessageBag):

use support\validation\Validator;

$data = ['email' => 'bad-email'];

$validator = Validator::make($data, [
    'email' => 'required|email',
]);

if ($validator->fails()) {
    $firstError = $validator->errors()->first();      // string
    $allErrors = $validator->errors()->all();         // array
    $errorsByField = $validator->errors()->toArray(); // array
    // handle errors...
}

การใช้ชุดกฎซ้ำ (ตัวตรวจสอบที่กำหนดเอง)

namespace app\validation;

use support\validation\Validator;

class UserValidator extends Validator
{
    protected array $rules = [
        'id' => 'required|integer|min:1',
        'name' => 'required|string|min:2|max:20',
        'email' => 'required|email',
    ];

    protected array $messages = [
        'name.required' => 'Name is required',
        'email.required' => 'Email is required',
        'email.email' => 'Invalid email format',
    ];

    protected array $attributes = [
        'name' => 'Name',
        'email' => 'Email',
    ];
}

การใช้การตรวจสอบแบบแมนนวลซ้ำ

use app\validation\UserValidator;

UserValidator::make($data)->validate();

การใช้ scenes (ตัวเลือก)

scenes เป็นฟีเจอร์ตัวเลือก จะตรวจสอบเฉพาะฟิลด์ย่อยเมื่อเรียก withScene(...)

namespace app\validation;

use support\validation\Validator;

class UserValidator extends Validator
{
    protected array $rules = [
        'id' => 'required|integer|min:1',
        'name' => 'required|string|min:2|max:20',
        'email' => 'required|email',
    ];

    protected array $scenes = [
        'create' => ['name', 'email'],
        'update' => ['id', 'name', 'email'],
    ];
}
use app\validation\UserValidator;

// ไม่ระบุ scene -> ตรวจสอบกฎทั้งหมด
UserValidator::make($data)->validate();

// ระบุ scene -> ตรวจสอบเฉพาะฟิลด์ใน scene นั้น
UserValidator::make($data)->withScene('create')->validate();

การตรวจสอบด้วย Annotation (ระดับเมธอด)

กฎโดยตรง

use support\Request;
use support\validation\annotation\Validate;

class AuthController
{
    #[Validate(
        rules: [
            'email' => 'required|email',
            'password' => 'required|string|min:6',
        ],
        messages: [
            'email.required' => 'Email is required',
            'password.required' => 'Password is required',
        ],
        attributes: [
            'email' => 'Email',
            'password' => 'Password',
        ]
    )]
    public function login(Request $request)
    {
        return json(['code' => 0, 'msg' => 'ok']);
    }
}

การใช้ชุดกฎซ้ำ

use app\validation\UserValidator;
use support\Request;
use support\validation\annotation\Validate;

class UserController
{
    #[Validate(validator: UserValidator::class, scene: 'create')]
    public function create(Request $request)
    {
        return json(['code' => 0, 'msg' => 'ok']);
    }
}

การตรวจสอบหลายชั้นซ้อนทับกัน

use support\validation\annotation\Validate;

class UserController
{
    #[Validate(rules: ['email' => 'required|email'])]
    #[Validate(rules: ['token' => 'required|string'])]
    public function send()
    {
        return json(['code' => 0, 'msg' => 'ok']);
    }
}

แหล่งข้อมูลการตรวจสอบ

use support\validation\annotation\Validate;

class UserController
{
    #[Validate(
        rules: ['email' => 'required|email'],
        in: ['query', 'body', 'path']
    )]
    public function send()
    {
        return json(['code' => 0, 'msg' => 'ok']);
    }
}

ใช้พารามิเตอร์ in เพื่อระบุแหล่งข้อมูล:

  • query พารามิเตอร์ query ของ HTTP request จาก $request->get()
  • body body ของ HTTP request จาก $request->post()
  • path พารามิเตอร์ path ของ HTTP request จาก $request->route->param()

in สามารถเป็น string หรือ array ได้ เมื่อเป็น array ค่าจะถูกรวมตามลำดับ โดยค่าที่มาทีหลังจะแทนที่ค่าก่อนหน้า เมื่อไม่ส่ง in ค่าเริ่มต้นคือ ['query', 'body', 'path']

การตรวจสอบระดับพารามิเตอร์ (Param)

การใช้งานพื้นฐาน

use support\validation\annotation\Param;

class MailController
{
    public function send(
        #[Param(rules: 'required|email')] string $from,
        #[Param(rules: 'required|email')] string $to,
        #[Param(rules: 'required|string|min:1|max:500')] string $content
    ) {
        return json(['code' => 0, 'msg' => 'ok']);
    }
}

แหล่งข้อมูลการตรวจสอบ

เช่นเดียวกัน การตรวจสอบระดับพารามิเตอร์ยังรองรับพารามิเตอร์ in เพื่อระบุแหล่งที่มา:

use support\validation\annotation\Param;

class MailController
{
    public function send(
        #[Param(rules: 'required|email', in: ['body'])] string $from
    ) {
        return json(['code' => 0, 'msg' => 'ok']);
    }
}

rules รองรับ string หรือ array

use support\validation\annotation\Param;

class MailController
{
    public function send(
        #[Param(rules: ['required', 'email'])] string $from
    ) {
        return json(['code' => 0, 'msg' => 'ok']);
    }
}

ข้อความ / attribute ที่กำหนดเอง

use support\validation\annotation\Param;

class UserController
{
    public function updateEmail(
        #[Param(
            rules: 'required|email',
            messages: ['email.email' => 'Invalid email format'],
            attribute: 'Email'
        )]
        string $email
    ) {
        return json(['code' => 0, 'msg' => 'ok']);
    }
}

การใช้ค่าคงที่ของกฎซ้ำ

final class ParamRules
{
    public const EMAIL = ['required', 'email'];
}

class UserController
{
    public function send(
        #[Param(rules: ParamRules::EMAIL)] string $email
    ) {
        return json(['code' => 0, 'msg' => 'ok']);
    }
}

การรวมระดับเมธอด + ระดับพารามิเตอร์

use support\Request;
use support\validation\annotation\Param;
use support\validation\annotation\Validate;

class UserController
{
    #[Validate(rules: ['token' => 'required|string'])]
    public function send(
        Request $request,
        #[Param(rules: 'required|email')] string $from,
        #[Param(rules: 'required|integer')] int $id
    ) {
        return json(['code' => 0, 'msg' => 'ok']);
    }
}

การอนุมานกฎอัตโนมัติ (อิงจากลายเซ็นพารามิเตอร์)

เมื่อใช้ #[Validate] บนเมธอด หรือพารามิเตอร์ใดๆ ของเมธอดนั้นใช้ #[Param] คอมโพเนนต์นี้จะอนุมานและเติมกฎการตรวจสอบพื้นฐานจากลายเซ็นพารามิเตอร์ของเมธอดโดยอัตโนมัติ จากนั้นรวมกับกฎที่มีอยู่ก่อนการตรวจสอบ

ตัวอย่าง: การขยายเทียบเท่า #[Validate]

1) เปิดใช้งาน #[Validate] โดยไม่เขียนกฎด้วยตนเอง:

use support\validation\annotation\Validate;

class DemoController
{
    #[Validate]
    public function create(string $content, int $uid)
    {
    }
}

เทียบเท่ากับ:

use support\validation\annotation\Validate;

class DemoController
{
    #[Validate(rules: [
        'content' => 'required|string',
        'uid' => 'required|integer',
    ])]
    public function create(string $content, int $uid)
    {
    }
}

2) เขียนกฎบางส่วนเท่านั้น ส่วนที่เหลือเติมจากลายเซ็นพารามิเตอร์:

use support\validation\annotation\Validate;

class DemoController
{
    #[Validate(rules: [
        'content' => 'min:2',
    ])]
    public function create(string $content, int $uid)
    {
    }
}

เทียบเท่ากับ:

use support\validation\annotation\Validate;

class DemoController
{
    #[Validate(rules: [
        'content' => 'required|string|min:2',
        'uid' => 'required|integer',
    ])]
    public function create(string $content, int $uid)
    {
    }
}

3) ค่าเริ่มต้น / ประเภท nullable:

use support\validation\annotation\Validate;

class DemoController
{
    #[Validate]
    public function create(string $content = 'default', ?int $uid = null)
    {
    }
}

เทียบเท่ากับ:

use support\validation\annotation\Validate;

class DemoController
{
    #[Validate(rules: [
        'content' => 'string',
        'uid' => 'integer|nullable',
    ])]
    public function create(string $content = 'default', ?int $uid = null)
    {
    }
}

การจัดการข้อยกเว้น

ข้อยกเว้นเริ่มต้น

การตรวจสอบล้มเหลวจะโยน support\validation\ValidationException โดยค่าเริ่มต้น ซึ่งสืบทอดจาก Webman\Exception\BusinessException และไม่บันทึกข้อผิดพลาด

พฤติกรรมการตอบกลับเริ่มต้นจัดการโดย BusinessException::render():

  • คำขอปกติ: คืนค่าข้อความ string เช่น token is required.
  • คำขอ JSON: คืนค่าการตอบกลับ JSON เช่น {"code": 422, "msg": "token is required.", "data":....}

การกำหนดการจัดการผ่านข้อยกเว้นที่กำหนดเอง

  • การกำหนดค่าทั่วโลก: exception ใน config/plugin/webman/validation/app.php

การรองรับหลายภาษา

คอมโพเนนต์มีชุดภาษาจีนและอังกฤษในตัว และรองรับการแทนที่ของโปรเจกต์ ลำดับการโหลด:

  1. ชุดภาษาของโปรเจกต์ resource/translations/{locale}/validation.php
  2. คอมโพเนนต์ในตัว vendor/webman/validation/resources/lang/{locale}/validation.php
  3. Illuminate อังกฤษในตัว (fallback)

หมายเหตุ
ภาษาเริ่มต้นของ Webman กำหนดใน config/translation.php หรือเปลี่ยนได้ผ่าน locale('en');

ตัวอย่างการแทนที่ในท้องถิ่น

resource/translations/zh_CN/validation.php

return [
    'email' => ':attribute is not a valid email format.',
];

การโหลด Middleware อัตโนมัติ

หลังการติดตั้ง คอมโพเนนต์จะโหลด validation middleware อัตโนมัติผ่าน config/plugin/webman/validation/middleware.php ไม่ต้องลงทะเบียนด้วยตนเอง

การสร้างด้วย Command-Line

ใช้คำสั่ง make:validator เพื่อสร้างคลาสตัวตรวจสอบ (ส่งออกไปยังไดเรกทอรี app/validation โดยค่าเริ่มต้น)

หมายเหตุ
ต้องใช้ composer require webman/console

การใช้งานพื้นฐาน

  • สร้างเทมเพลตว่าง
php webman make:validator UserValidator
  • เขียนทับไฟล์ที่มีอยู่
php webman make:validator UserValidator --force
php webman make:validator UserValidator -f

สร้างกฎจากโครงสร้างตาราง

  • ระบุชื่อตารางเพื่อสร้างกฎพื้นฐาน (อนุมาน $rules จากประเภทฟิลด์/nullable/ความยาว ฯลฯ ไม่รวมฟิลด์ที่เกี่ยวกับ ORM โดยค่าเริ่มต้น: laravel ใช้ created_at/updated_at/deleted_at thinkorm ใช้ create_time/update_time/delete_time)
php webman make:validator UserValidator --table=wa_users
php webman make:validator UserValidator -t wa_users
  • ระบุการเชื่อมต่อฐานข้อมูล (สถานการณ์การเชื่อมต่อหลายตัว)
php webman make:validator UserValidator --table=wa_users --database=mysql
php webman make:validator UserValidator -t wa_users -d mysql

Scenes

  • สร้าง CRUD scenes: create/update/delete/detail
php webman make:validator UserValidator --table=wa_users --scenes=crud
php webman make:validator UserValidator -t wa_users -s crud

scene update รวมฟิลด์คีย์หลัก (สำหรับระบุเรคอร์ด) และฟิลด์อื่นๆ delete/detail รวมเฉพาะคีย์หลักโดยค่าเริ่มต้น

การเลือก ORM (laravel (illuminate/database) vs think-orm)

  • เลือกอัตโนมัติ (ค่าเริ่มต้น): ใช้ตัวที่ติดตั้ง/กำหนดค่าไว้ เมื่อมีทั้งสองตัว ใช้ illuminate โดยค่าเริ่มต้น
  • บังคับระบุ
php webman make:validator UserValidator --table=wa_users --orm=laravel
php webman make:validator UserValidator --table=wa_users --orm=thinkorm
php webman make:validator UserValidator -t wa_users -o thinkorm

ตัวอย่างสมบูรณ์

php webman make:validator UserValidator -t wa_users -d mysql -s crud -o laravel -f

Unit Tests

จากไดเรกทอรีราก webman/validation รัน:

composer install
vendor\bin\phpunit -c phpunit.xml

อ้างอิงกฎการตรวจสอบ

กฎการตรวจสอบที่มีให้ใช้

[!IMPORTANT]

  • Webman Validation อิงจาก illuminate/validation ชื่อกฎตรงกับ Laravel และไม่มีกฎเฉพาะของ Webman
  • Middleware ตรวจสอบข้อมูลจาก $request->all() (GET+POST) รวมกับพารามิเตอร์ route โดยค่าเริ่มต้น ไม่รวมไฟล์ที่อัปโหลด สำหรับกฎไฟล์ ให้รวม $request->file() เข้ากับข้อมูลด้วยตนเอง หรือเรียก Validator::make แบบแมนนวล
  • current_password ขึ้นอยู่กับ auth guard; exists/unique ขึ้นอยู่กับการเชื่อมต่อฐานข้อมูลและ query builder กฎเหล่านี้ไม่พร้อมใช้งานเมื่อคอมโพเนนต์ที่เกี่ยวข้องไม่ได้รวมอยู่

รายการด้านล่างคือกฎการตรวจสอบทั้งหมดที่มีให้ใช้และวัตถุประสงค์:

Boolean

[Accepted](#rule-accepted) [Accepted If](#rule-accepted-if) [Boolean](#rule-boolean) [Declined](#rule-declined) [Declined If](#rule-declined-if)

String

[Active URL](#rule-active-url) [Alpha](#rule-alpha) [Alpha Dash](#rule-alpha-dash) [Alpha Numeric](#rule-alpha-num) [Ascii](#rule-ascii) [Confirmed](#rule-confirmed) [Current Password](#rule-current-password) [Different](#rule-different) [Doesnt Start With](#rule-doesnt-start-with) [Doesnt End With](#rule-doesnt-end-with) [Email](#rule-email) [Ends With](#rule-ends-with) [Enum](#rule-enum) [Hex Color](#rule-hex-color) [In](#rule-in) [IP Address](#rule-ip) [IPv4](#rule-ipv4) [IPv6](#rule-ipv6) [JSON](#rule-json) [Lowercase](#rule-lowercase) [MAC Address](#rule-mac) [Max](#rule-max) [Min](#rule-min) [Not In](#rule-not-in) [Regular Expression](#rule-regex) [Not Regular Expression](#rule-not-regex) [Same](#rule-same) [Size](#rule-size) [Starts With](#rule-starts-with) [String](#rule-string) [Uppercase](#rule-uppercase) [URL](#rule-url) [ULID](#rule-ulid) [UUID](#rule-uuid)

Numeric

[Between](#rule-between) [Decimal](#rule-decimal) [Different](#rule-different) [Digits](#rule-digits) [Digits Between](#rule-digits-between) [Greater Than](#rule-gt) [Greater Than Or Equal](#rule-gte) [Integer](#rule-integer) [Less Than](#rule-lt) [Less Than Or Equal](#rule-lte) [Max](#rule-max) [Max Digits](#rule-max-digits) [Min](#rule-min) [Min Digits](#rule-min-digits) [Multiple Of](#rule-multiple-of) [Numeric](#rule-numeric) [Same](#rule-same) [Size](#rule-size)

Array

[Array](#rule-array) [Between](#rule-between) [Contains](#rule-contains) [Doesnt Contain](#rule-doesnt-contain) [Distinct](#rule-distinct) [In Array](#rule-in-array) [In Array Keys](#rule-in-array-keys) [List](#rule-list) [Max](#rule-max) [Min](#rule-min) [Size](#rule-size)

Date

[After](#rule-after) [After Or Equal](#rule-after-or-equal) [Before](#rule-before) [Before Or Equal](#rule-before-or-equal) [Date](#rule-date) [Date Equals](#rule-date-equals) [Date Format](#rule-date-format) [Different](#rule-different) [Timezone](#rule-timezone)

File

[Between](#rule-between) [Dimensions](#rule-dimensions) [Encoding](#rule-encoding) [Extensions](#rule-extensions) [File](#rule-file) [Image](#rule-image) [Max](#rule-max) [MIME Types](#rule-mimetypes) [MIME Type By File Extension](#rule-mimes) [Size](#rule-size)

Database

[Exists](#rule-exists) [Unique](#rule-unique)

Utility

[Any Of](#rule-anyof) [Bail](#rule-bail) [Exclude](#rule-exclude) [Exclude If](#rule-exclude-if) [Exclude Unless](#rule-exclude-unless) [Exclude With](#rule-exclude-with) [Exclude Without](#rule-exclude-without) [Filled](#rule-filled) [Missing](#rule-missing) [Missing If](#rule-missing-if) [Missing Unless](#rule-missing-unless) [Missing With](#rule-missing-with) [Missing With All](#rule-missing-with-all) [Nullable](#rule-nullable) [Present](#rule-present) [Present If](#rule-present-if) [Present Unless](#rule-present-unless) [Present With](#rule-present-with) [Present With All](#rule-present-with-all) [Prohibited](#rule-prohibited) [Prohibited If](#rule-prohibited-if) [Prohibited If Accepted](#rule-prohibited-if-accepted) [Prohibited If Declined](#rule-prohibited-if-declined) [Prohibited Unless](#rule-prohibited-unless) [Prohibits](#rule-prohibits) [Required](#rule-required) [Required If](#rule-required-if) [Required If Accepted](#rule-required-if-accepted) [Required If Declined](#rule-required-if-declined) [Required Unless](#rule-required-unless) [Required With](#rule-required-with) [Required With All](#rule-required-with-all) [Required Without](#rule-required-without) [Required Without All](#rule-required-without-all) [Required Array Keys](#rule-required-array-keys) [Sometimes](#validating-when-present)

accepted

ฟิลด์ต้องเป็น "yes", "on", 1, "1", true หรือ "true" มักใช้สำหรับสถานการณ์เช่นการยืนยันว่าผู้ใช้ยอมรับข้อกำหนดการให้บริการ

accepted_if:anotherfield,value,...

เมื่อฟิลด์อื่นเท่ากับค่าที่ระบุ ฟิลด์ต้องเป็น "yes", "on", 1, "1", true หรือ "true" มักใช้สำหรับสถานการณ์การยอมรับแบบมีเงื่อนไข

active_url

ฟิลด์ต้องมีเรคอร์ด A หรือ AAAA ที่ถูกต้อง กฎนี้ใช้ parse_url เพื่อแยก hostname ของ URL ก่อน จากนั้นตรวจสอบด้วย dns_get_record

after:date

ฟิลด์ต้องเป็นค่าหลังวันที่กำหนด วันที่จะถูกส่งไปยัง strtotime เพื่อแปลงเป็น DateTime ที่ถูกต้อง:

use support\validation\Validator;

Validator::make($data, [
    'start_date' => 'required|date|after:tomorrow',
])->validate();

สามารถส่งชื่อฟิลด์อื่นเพื่อเปรียบเทียบได้:

Validator::make($data, [
    'finish_date' => 'required|date|after:start_date',
])->validate();

สามารถใช้ตัวสร้างกฎ date แบบ fluent ได้:

use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'start_date' => [
        'required',
        Rule::date()->after(\Carbon\Carbon::today()->addDays(7)),
    ],
])->validate();

afterToday และ todayOrAfter แสดงความหมาย "ต้องหลังวันนี้" หรือ "ต้องเป็นวันนี้หรือหลังจากนี้" ได้สะดวก:

Validator::make($data, [
    'start_date' => [
        'required',
        Rule::date()->afterToday(),
    ],
])->validate();

after_or_equal:date

ฟิลด์ต้องอยู่ในหรือหลังวันที่กำหนด ดู after สำหรับรายละเอียดเพิ่มเติม

สามารถใช้ตัวสร้างกฎ date แบบ fluent ได้:

use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'start_date' => [
        'required',
        Rule::date()->afterOrEqual(\Carbon\Carbon::today()->addDays(7)),
    ],
])->validate();

anyOf

Rule::anyOf อนุญาตให้ระบุ "เป็นไปตามชุดกฎใดชุดหนึ่ง" ตัวอย่างเช่น กฎต่อไปนี้หมายความว่า username ต้องเป็นอีเมลหรือสตริงตัวอักษร/ตัวเลข/ขีดล่าง/ขีดกลางอย่างน้อย 6 ตัวอักษร:

use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'username' => [
        'required',
        Rule::anyOf([
            ['string', 'email'],
            ['string', 'alpha_dash', 'min:6'],
        ]),
    ],
])->validate();

alpha

ฟิลด์ต้องเป็นตัวอักษร Unicode (\p{L} และ \p{M})

เพื่ออนุญาตเฉพาะ ASCII (a-z, A-Z) เท่านั้น ให้เพิ่มตัวเลือก ascii:

Validator::make($data, [
    'username' => 'alpha:ascii',
])->validate();

alpha_dash

ฟิลด์อาจมีเฉพาะตัวอักษรและตัวเลข Unicode (\p{L}, \p{M}, \p{N}) บวกขีด (-) และขีดล่าง (_) ของ ASCII

เพื่ออนุญาตเฉพาะ ASCII (a-z, A-Z, 0-9) เท่านั้น ให้เพิ่มตัวเลือก ascii:

Validator::make($data, [
    'username' => 'alpha_dash:ascii',
])->validate();

alpha_num

ฟิลด์อาจมีเฉพาะตัวอักษรและตัวเลข Unicode (\p{L}, \p{M}, \p{N})

เพื่ออนุญาตเฉพาะ ASCII (a-z, A-Z, 0-9) เท่านั้น ให้เพิ่มตัวเลือก ascii:

Validator::make($data, [
    'username' => 'alpha_num:ascii',
])->validate();

array

ฟิลด์ต้องเป็น PHP array

เมื่อกฎ array มีพารามิเตอร์เพิ่มเติม คีย์ของอาร์เรย์อินพุตต้องอยู่ในรายการพารามิเตอร์ ในตัวอย่าง คีย์ admin ไม่อยู่ในรายการที่อนุญาต จึงไม่ถูกต้อง:

use support\validation\Validator;

$input = [
    'user' => [
        'name' => 'Taylor Otwell',
        'username' => 'taylorotwell',
        'admin' => true,
    ],
];

Validator::make($input, [
    'user' => 'array:name,username',
])->validate();

แนะนำให้กำหนดคีย์อาร์เรย์ที่อนุญาตอย่างชัดเจนในโปรเจกต์จริง

ascii

ฟิลด์อาจมีเฉพาะอักขระ ASCII 7-bit

bail

หยุดตรวจสอบกฎถัดไปสำหรับฟิลด์เมื่อกฎแรกล้มเหลว

กฎนี้มีผลเฉพาะฟิลด์ปัจจุบัน สำหรับ "หยุดเมื่อล้มเหลวครั้งแรกทั่วโลก" ให้ใช้ validator ของ Illuminate โดยตรงและเรียก stopOnFirstFailure()

before:date

ฟิลด์ต้องอยู่ก่อนวันที่กำหนด วันที่จะถูกส่งไปยัง strtotime เพื่อแปลงเป็น DateTime ที่ถูกต้อง เช่นเดียวกับ after สามารถส่งชื่อฟิลด์อื่นเพื่อเปรียบเทียบได้

สามารถใช้ตัวสร้างกฎ date แบบ fluent ได้:

use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'start_date' => [
        'required',
        Rule::date()->before(\Carbon\Carbon::today()->subDays(7)),
    ],
])->validate();

beforeToday และ todayOrBefore แสดงความหมาย "ต้องก่อนวันนี้" หรือ "ต้องเป็นวันนี้หรือก่อนหน้า" ได้สะดวก:

Validator::make($data, [
    'start_date' => [
        'required',
        Rule::date()->beforeToday(),
    ],
])->validate();

before_or_equal:date

ฟิลด์ต้องอยู่ในหรือก่อนวันที่กำหนด วันที่จะถูกส่งไปยัง strtotime เพื่อแปลงเป็น DateTime ที่ถูกต้อง เช่นเดียวกับ after สามารถส่งชื่อฟิลด์อื่นเพื่อเปรียบเทียบได้

สามารถใช้ตัวสร้างกฎ date แบบ fluent ได้:

use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'start_date' => [
        'required',
        Rule::date()->beforeOrEqual(\Carbon\Carbon::today()->subDays(7)),
    ],
])->validate();

between:min,max

ขนาดฟิลด์ต้องอยู่ระหว่าง min และ max (รวม) การประเมินสำหรับสตริง ตัวเลข อาร์เรย์ และไฟล์เหมือนกับ size

boolean

ฟิลด์ต้องแปลงเป็น boolean ได้ ค่าอินพุตที่ยอมรับได้รวมถึง true, false, 1, 0, "1", "0"

ใช้พารามิเตอร์ strict เพื่ออนุญาตเฉพาะ true หรือ false:

Validator::make($data, [
    'foo' => 'boolean:strict',
])->validate();

confirmed

ฟิลด์ต้องมีฟิลด์ {field}_confirmation ที่ตรงกัน ตัวอย่างเช่น เมื่อฟิลด์เป็น password ต้องมี password_confirmation

สามารถระบุชื่อฟิลด์ยืนยันที่กำหนดเองได้ เช่น confirmed:repeat_username ต้องการให้ repeat_username ตรงกับฟิลด์ปัจจุบัน

contains:foo,bar,...

ฟิลด์ต้องเป็นอาร์เรย์และต้องมีค่าพารามิเตอร์ที่กำหนดทั้งหมด กฎนี้มักใช้สำหรับการตรวจสอบอาร์เรย์ สามารถใช้ Rule::contains เพื่อสร้าง:

use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'roles' => [
        'required',
        'array',
        Rule::contains(['admin', 'editor']),
    ],
])->validate();

doesnt_contain:foo,bar,...

ฟิลด์ต้องเป็นอาร์เรย์และต้องไม่มีค่าพารามิเตอร์ที่กำหนดใดๆ สามารถใช้ Rule::doesntContain เพื่อสร้าง:

use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'roles' => [
        'required',
        'array',
        Rule::doesntContain(['admin', 'editor']),
    ],
])->validate();

current_password

ฟิลด์ต้องตรงกับรหัสผ่านของผู้ใช้ที่รับรองความถูกต้องปัจจุบัน สามารถระบุ auth guard เป็นพารามิเตอร์แรก:

Validator::make($data, [
    'password' => 'current_password:api',
])->validate();

[!WARNING]
กฎนี้ขึ้นอยู่กับคอมโพเนนต์ auth และการกำหนดค่า guard อย่าใช้เมื่อไม่ได้รวม auth

date

ฟิลด์ต้องเป็นวันที่ที่ถูกต้อง (ไม่ใช่แบบสัมพัทธ์) ที่ strtotime รู้จักได้

date_equals:date

ฟิลด์ต้องเท่ากับวันที่กำหนด วันที่จะถูกส่งไปยัง strtotime เพื่อแปลงเป็น DateTime ที่ถูกต้อง

date_format:format,...

ฟิลด์ต้องตรงกับรูปแบบที่กำหนดอย่างน้อยหนึ่งรูปแบบ ใช้ date หรือ date_format อย่างใดอย่างหนึ่ง กฎนี้รองรับรูปแบบ DateTime ทั้งหมดของ PHP

สามารถใช้ตัวสร้างกฎ date แบบ fluent ได้:

use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'start_date' => [
        'required',
        Rule::date()->format('Y-m-d'),
    ],
])->validate();

decimal:min,max

ฟิลด์ต้องเป็นตัวเลขที่มีทศนิยมตามที่ต้องการ:

Validator::make($data, [
    'price' => 'decimal:2',
])->validate();

Validator::make($data, [
    'price' => 'decimal:2,4',
])->validate();

declined

ฟิลด์ต้องเป็น "no", "off", 0, "0", false หรือ "false"

declined_if:anotherfield,value,...

เมื่อฟิลด์อื่นเท่ากับค่าที่ระบุ ฟิลด์ต้องเป็น "no", "off", 0, "0", false หรือ "false"

different:field

ฟิลด์ต้องแตกต่างจาก field

digits:value

ฟิลด์ต้องเป็นจำนวนเต็มที่มีความยาว value

digits_between:min,max

ฟิลด์ต้องเป็นจำนวนเต็มที่มีความยาวระหว่าง min และ max

dimensions

ฟิลด์ต้องเป็นรูปภาพและเป็นไปตามข้อจำกัดมิติ:

Validator::make($data, [
    'avatar' => 'dimensions:min_width=100,min_height=200',
])->validate();

ข้อจำกัดที่มี: min_width, max_width, min_height, max_height, width, height, ratio

ratio คืออัตราส่วนภาพ สามารถแสดงเป็นเศษส่วนหรือ float:

Validator::make($data, [
    'avatar' => 'dimensions:ratio=3/2',
])->validate();

กฎนี้มีพารามิเตอร์มาก แนะนำให้ใช้ Rule::dimensions เพื่อสร้าง:

use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'avatar' => [
        'required',
        Rule::dimensions()
            ->maxWidth(1000)
            ->maxHeight(500)
            ->ratio(3 / 2),
    ],
])->validate();

distinct

เมื่อตรวจสอบอาร์เรย์ ค่าฟิลด์ต้องไม่ซ้ำกัน:

Validator::make($data, [
    'foo.*.id' => 'distinct',
])->validate();

ใช้การเปรียบเทียบแบบหลวมโดยค่าเริ่มต้น เพิ่ม strict สำหรับการเปรียบเทียบแบบเข้มงวด:

Validator::make($data, [
    'foo.*.id' => 'distinct:strict',
])->validate();

เพิ่ม ignore_case เพื่อไม่สนใจความแตกต่างของตัวพิมพ์:

Validator::make($data, [
    'foo.*.id' => 'distinct:ignore_case',
])->validate();

doesnt_start_with:foo,bar,...

ฟิลด์ต้องไม่ขึ้นต้นด้วยค่าที่ระบุใดๆ

doesnt_end_with:foo,bar,...

ฟิลด์ต้องไม่ลงท้ายด้วยค่าที่ระบุใดๆ

email

ฟิลด์ต้องเป็นที่อยู่อีเมลที่ถูกต้อง กฎนี้ขึ้นอยู่กับ egulias/email-validator ใช้ RFCValidation โดยค่าเริ่มต้น และสามารถใช้วิธีการตรวจสอบอื่นได้:

Validator::make($data, [
    'email' => 'email:rfc,dns',
])->validate();

วิธีการตรวจสอบที่มี:

- `rfc`: `RFCValidation` - ตรวจสอบอีเมลตาม spec ของ RFC ([supported RFCs](https://github.com/egulias/EmailValidator?tab=readme-ov-file#supported-rfcs)) - `strict`: `NoRFCWarningsValidation` - ล้มเหลวเมื่อมีคำเตือน RFC (เช่น จุดต่อท้ายหรือจุดติดกัน) - `dns`: `DNSCheckValidation` - ตรวจสอบว่าโดเมนมีเรคอร์ด MX ที่ถูกต้องหรือไม่ - `spoof`: `SpoofCheckValidation` - ป้องกันอักขระ Unicode แบบ homograph หรือ spoofing - `filter`: `FilterEmailValidation` - ตรวจสอบโดยใช้ PHP `filter_var` - `filter_unicode`: `FilterEmailValidation::unicode()` - การตรวจสอบ `filter_var` ที่อนุญาต Unicode

สามารถใช้ตัวสร้างกฎแบบ fluent ได้:

use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'email' => [
        'required',
        Rule::email()
            ->rfcCompliant(strict: false)
            ->validateMxRecord()
            ->preventSpoofing(),
    ],
])->validate();

[!WARNING]
dns และ spoof ต้องการส่วนขยาย PHP intl

encoding:encoding_type

ฟิลด์ต้องตรงกับ character encoding ที่ระบุ กฎนี้ใช้ mb_check_encoding เพื่อตรวจจับ encoding ของไฟล์หรือสตริง สามารถใช้กับตัวสร้างกฎไฟล์ได้:

use Illuminate\Validation\Rules\File;
use support\validation\Validator;

Validator::make($data, [
    'attachment' => [
        'required',
        File::types(['csv'])->encoding('utf-8'),
    ],
])->validate();

ends_with:foo,bar,...

ฟิลด์ต้องลงท้ายด้วยค่าที่ระบุอย่างน้อยหนึ่งค่า

enum

Enum เป็นกฎแบบคลาสสำหรับตรวจสอบว่าค่าฟิลด์เป็นค่า enum ที่ถูกต้อง ส่งชื่อคลาส enum เมื่อสร้าง สำหรับค่าดั้งเดิม ให้ใช้ Backed Enum:

use app\enums\ServerStatus;
use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'status' => [Rule::enum(ServerStatus::class)],
])->validate();

ใช้ only/except เพื่อจำกัดค่าของ enum:

use app\enums\ServerStatus;
use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'status' => [
        Rule::enum(ServerStatus::class)
            ->only([ServerStatus::Pending, ServerStatus::Active]),
    ],
])->validate();

Validator::make($data, [
    'status' => [
        Rule::enum(ServerStatus::class)
            ->except([ServerStatus::Pending, ServerStatus::Active]),
    ],
])->validate();

ใช้ when สำหรับข้อจำกัดแบบมีเงื่อนไข:

use app\Enums\ServerStatus;
use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'status' => [
        Rule::enum(ServerStatus::class)->when(
            $isAdmin,
            fn ($rule) => $rule->only(ServerStatus::Active),
            fn ($rule) => $rule->only(ServerStatus::Pending),
        ),
    ],
])->validate();

exclude

ฟิลด์จะถูกแยกออกจากข้อมูลที่คืนโดย validate/validated

exclude_if:anotherfield,value

เมื่อ anotherfield เท่ากับ value ฟิลด์จะถูกแยกออกจากข้อมูลที่คืนโดย validate/validated

สำหรับเงื่อนไขที่ซับซ้อน ให้ใช้ Rule::excludeIf:

use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'role_id' => Rule::excludeIf($isAdmin),
])->validate();

Validator::make($data, [
    'role_id' => Rule::excludeIf(fn () => $isAdmin),
])->validate();

exclude_unless:anotherfield,value

เว้นแต่ anotherfield จะเท่ากับ value ฟิลด์จะถูกแยกออกจากข้อมูลที่คืนโดย validate/validated หาก value เป็น null (เช่น exclude_unless:name,null) ฟิลด์จะถูกเก็บไว้เฉพาะเมื่อฟิลด์เปรียบเทียบเป็น null หรือไม่มี

exclude_with:anotherfield

เมื่อ anotherfield มีอยู่ ฟิลด์จะถูกแยกออกจากข้อมูลที่คืนโดย validate/validated

exclude_without:anotherfield

เมื่อ anotherfield ไม่มีอยู่ ฟิลด์จะถูกแยกออกจากข้อมูลที่คืนโดย validate/validated

exists:table,column

ฟิลด์ต้องมีอยู่ในตารางฐานข้อมูลที่ระบุ

การใช้งานพื้นฐานของกฎ Exists

Validator::make($data, [
    'state' => 'exists:states',
])->validate();

เมื่อไม่ระบุ column จะใช้ชื่อฟิลด์โดยค่าเริ่มต้น ดังนั้นตัวอย่างนี้ตรวจสอบว่าคอลัมน์ state มีอยู่ในตาราง states หรือไม่

การระบุชื่อคอลัมน์ที่กำหนดเอง

ต่อชื่อคอลัมน์หลังชื่อตาราง:

Validator::make($data, [
    'state' => 'exists:states,abbreviation',
])->validate();

เพื่อระบุการเชื่อมต่อฐานข้อมูล นำหน้าชื่อตารางด้วยชื่อการเชื่อมต่อ:

Validator::make($data, [
    'email' => 'exists:connection.staff,email',
])->validate();

สามารถส่งชื่อคลาส model ได้ เฟรมเวิร์กจะแก้ไขชื่อตาราง:

Validator::make($data, [
    'user_id' => 'exists:app\model\User,id',
])->validate();

สำหรับเงื่อนไข query ที่กำหนดเอง ให้ใช้ตัวสร้าง Rule:

use Illuminate\Database\Query\Builder;
use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'email' => [
        'required',
        Rule::exists('staff')->where(function (Builder $query) {
            $query->where('account_id', 1);
        }),
    ],
])->validate();

สามารถระบุชื่อคอลัมน์โดยตรงใน Rule::exists ได้:

use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'state' => [Rule::exists('states', 'abbreviation')],
])->validate();

เพื่อตรวจสอบว่าชุดค่ามีอยู่ ให้รวมกับกฎ array:

Validator::make($data, [
    'states' => ['array', Rule::exists('states', 'abbreviation')],
])->validate();

เมื่อมีทั้ง array และ exists การ query เดียวจะตรวจสอบค่าทั้งหมด

extensions:foo,bar,...

ตรวจสอบว่านามสกุลไฟล์ที่อัปโหลดอยู่ในรายการที่อนุญาต:

Validator::make($data, [
    'photo' => ['required', 'extensions:jpg,png'],
])->validate();

[!WARNING]
อย่าพึ่งพานามสกุลอย่างเดียวในการตรวจสอบประเภทไฟล์ ให้ใช้ร่วมกับ mimes หรือ mimetypes

file

ฟิลด์ต้องเป็นไฟล์ที่อัปโหลดสำเร็จ

filled

เมื่อฟิลด์มีอยู่ ค่าของมันต้องไม่ว่าง

gt:field

ฟิลด์ต้องมากกว่าฟิลด์หรือค่าที่กำหนด field ทั้งสองต้องมีประเภทเดียวกัน การประเมินสำหรับสตริง ตัวเลข อาร์เรย์ และไฟล์เหมือนกับ size

gte:field

ฟิลด์ต้องมากกว่าหรือเท่ากับฟิลด์หรือค่าที่กำหนด field ทั้งสองต้องมีประเภทเดียวกัน การประเมินสำหรับสตริง ตัวเลข อาร์เรย์ และไฟล์เหมือนกับ size

hex_color

ฟิลด์ต้องเป็นค่า hex color ที่ถูกต้อง

image

ฟิลด์ต้องเป็นรูปภาพ (jpg, jpeg, png, bmp, gif หรือ webp)

[!WARNING]
SVG ไม่ได้รับอนุญาตโดยค่าเริ่มต้นเนื่องจากความเสี่ยง XSS เพื่ออนุญาต ให้เพิ่ม allow_svg: image:allow_svg

in:foo,bar,...

ฟิลด์ต้องอยู่ในรายการค่าที่กำหนด สามารถใช้ Rule::in เพื่อสร้าง:

use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'zones' => [
        'required',
        Rule::in(['first-zone', 'second-zone']),
    ],
])->validate();

เมื่อรวมกับกฎ array แต่ละค่าในอาร์เรย์อินพุตต้องอยู่ในรายการ in:

use support\validation\Rule;
use support\validation\Validator;

$input = [
    'airports' => ['NYC', 'LAS'],
];

Validator::make($input, [
    'airports' => [
        'required',
        'array',
    ],
    'airports.*' => Rule::in(['NYC', 'LIT']),
])->validate();

in_array:anotherfield.*

ฟิลด์ต้องมีอยู่ในรายการค่าของ anotherfield

in_array_keys:value.*

ฟิลด์ต้องเป็นอาร์เรย์และต้องมีค่าที่กำหนดอย่างน้อยหนึ่งค่าเป็นคีย์:

Validator::make($data, [
    'config' => 'array|in_array_keys:timezone',
])->validate();

integer

ฟิลด์ต้องเป็นจำนวนเต็ม

ใช้พารามิเตอร์ strict เพื่อให้ฟิลด์ต้องเป็นประเภท integer เท่านั้น จำนวนเต็มที่เป็นสตริงจะไม่ถูกต้อง:

Validator::make($data, [
    'age' => 'integer:strict',
])->validate();

[!WARNING]
กฎนี้ตรวจสอบเฉพาะว่าผ่าน PHP FILTER_VALIDATE_INT หรือไม่ สำหรับประเภทตัวเลขแบบเข้มงวด ให้ใช้ร่วมกับ numeric

ip

ฟิลด์ต้องเป็นที่อยู่ IP ที่ถูกต้อง

ipv4

ฟิลด์ต้องเป็นที่อยู่ IPv4 ที่ถูกต้อง

ipv6

ฟิลด์ต้องเป็นที่อยู่ IPv6 ที่ถูกต้อง

json

ฟิลด์ต้องเป็นสตริง JSON ที่ถูกต้อง

lt:field

ฟิลด์ต้องน้อยกว่าฟิลด์ที่กำหนด field ทั้งสองต้องมีประเภทเดียวกัน การประเมินสำหรับสตริง ตัวเลข อาร์เรย์ และไฟล์เหมือนกับ size

lte:field

ฟิลด์ต้องน้อยกว่าหรือเท่ากับฟิลด์ที่กำหนด field ทั้งสองต้องมีประเภทเดียวกัน การประเมินสำหรับสตริง ตัวเลข อาร์เรย์ และไฟล์เหมือนกับ size

lowercase

ฟิลด์ต้องเป็นตัวพิมพ์เล็ก

list

ฟิลด์ต้องเป็นอาร์เรย์ list คีย์ของอาร์เรย์ list ต้องเป็นตัวเลขต่อเนื่องตั้งแต่ 0 ถึง count($array) - 1

mac_address

ฟิลด์ต้องเป็นที่อยู่ MAC ที่ถูกต้อง

max:value

ฟิลด์ต้องน้อยกว่าหรือเท่ากับ value การประเมินสำหรับสตริง ตัวเลข อาร์เรย์ และไฟล์เหมือนกับ size

max_digits:value

ฟิลด์ต้องเป็นจำนวนเต็มที่มีความยาวไม่เกิน value

mimetypes:text/plain,...

ตรวจสอบว่า MIME type ของไฟล์อยู่ในรายการ:

Validator::make($data, [
    'video' => 'mimetypes:video/avi,video/mpeg,video/quicktime',
])->validate();

MIME type ถูกคาดเดาจากการอ่านเนื้อหาไฟล์ และอาจแตกต่างจาก MIME ที่ไคลเอนต์ให้มา

mimes:foo,bar,...

ตรวจสอบว่า MIME type ของไฟล์ตรงกับนามสกุลที่กำหนด:

Validator::make($data, [
    'photo' => 'mimes:jpg,bmp,png',
])->validate();

แม้พารามิเตอร์จะเป็นนามสกุล กฎนี้อ่านเนื้อหาไฟล์เพื่อกำหนด MIME การแมปนามสกุลกับ MIME:

https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types

MIME types และ extensions

กฎนี้ไม่ตรวจสอบว่า "นามสกุลไฟล์" ตรงกับ "MIME จริง" หรือไม่ ตัวอย่างเช่น mimes:png ถือว่า photo.txt ที่มีเนื้อหา PNG เป็นถูกต้อง เพื่อตรวจสอบนามสกุล ให้ใช้ extensions

min:value

ฟิลด์ต้องมากกว่าหรือเท่ากับ value การประเมินสำหรับสตริง ตัวเลข อาร์เรย์ และไฟล์เหมือนกับ size

min_digits:value

ฟิลด์ต้องเป็นจำนวนเต็มที่มีความยาวไม่น้อยกว่า value

multiple_of:value

ฟิลด์ต้องเป็นพหุคูณของ value

missing

ฟิลด์ต้องไม่มีอยู่ในข้อมูลอินพุต

missing_if:anotherfield,value,...

เมื่อ anotherfield เท่ากับ value ใดๆ ฟิลด์ต้องไม่มีอยู่

missing_unless:anotherfield,value

เว้นแต่ anotherfield จะเท่ากับ value ใดๆ ฟิลด์ต้องไม่มีอยู่

missing_with:foo,bar,...

เมื่อฟิลด์ที่ระบุใดๆ มีอยู่ ฟิลด์ต้องไม่มีอยู่

missing_with_all:foo,bar,...

เมื่อฟิลด์ที่ระบุทั้งหมดมีอยู่ ฟิลด์ต้องไม่มีอยู่

not_in:foo,bar,...

ฟิลด์ต้องไม่อยู่ในรายการค่าที่กำหนด สามารถใช้ Rule::notIn เพื่อสร้าง:

use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'toppings' => [
        'required',
        Rule::notIn(['sprinkles', 'cherries']),
    ],
])->validate();

not_regex:pattern

ฟิลด์ต้องไม่ตรงกับ regular expression ที่กำหนด

กฎนี้ใช้ PHP preg_match regex ต้องมีตัวคั่น เช่น 'email' => 'not_regex:/^.+$/i'

[!WARNING]
เมื่อใช้ regex/not_regex หาก regex มี | ให้ใช้รูปแบบ array เพื่อหลีกเลี่ยงความขัดแย้งกับตัวคั่น |

nullable

ฟิลด์อาจเป็น null

numeric

ฟิลด์ต้องเป็น numeric

ใช้พารามิเตอร์ strict เพื่ออนุญาตเฉพาะประเภท integer หรือ float เท่านั้น สตริงตัวเลขจะไม่ถูกต้อง:

Validator::make($data, [
    'amount' => 'numeric:strict',
])->validate();

present

ฟิลด์ต้องมีอยู่ในข้อมูลอินพุต

present_if:anotherfield,value,...

เมื่อ anotherfield เท่ากับ value ใดๆ ฟิลด์ต้องมีอยู่

present_unless:anotherfield,value

เว้นแต่ anotherfield จะเท่ากับ value ใดๆ ฟิลด์ต้องมีอยู่

present_with:foo,bar,...

เมื่อฟิลด์ที่ระบุใดๆ มีอยู่ ฟิลด์ต้องมีอยู่

present_with_all:foo,bar,...

เมื่อฟิลด์ที่ระบุทั้งหมดมีอยู่ ฟิลด์ต้องมีอยู่

prohibited

ฟิลด์ต้องไม่มีหรือว่าง "ว่าง" หมายถึง:

- ค่าเป็น `null` - ค่าเป็นสตริงว่าง - ค่าเป็นอาร์เรย์ว่างหรืออ็อบเจกต์ `Countable` ว่าง - ไฟล์ที่อัปโหลดที่มี path ว่าง

prohibited_if:anotherfield,value,...

เมื่อ anotherfield เท่ากับ value ใดๆ ฟิลด์ต้องไม่มีหรือว่าง "ว่าง" หมายถึง:

- ค่าเป็น `null` - ค่าเป็นสตริงว่าง - ค่าเป็นอาร์เรย์ว่างหรืออ็อบเจกต์ `Countable` ว่าง - ไฟล์ที่อัปโหลดที่มี path ว่าง

สำหรับเงื่อนไขที่ซับซ้อน ให้ใช้ Rule::prohibitedIf:

use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'role_id' => Rule::prohibitedIf($isAdmin),
])->validate();

Validator::make($data, [
    'role_id' => Rule::prohibitedIf(fn () => $isAdmin),
])->validate();

prohibited_if_accepted:anotherfield,...

เมื่อ anotherfield เป็น "yes", "on", 1, "1", true หรือ "true" ฟิลด์ต้องไม่มีหรือว่าง

prohibited_if_declined:anotherfield,...

เมื่อ anotherfield เป็น "no", "off", 0, "0", false หรือ "false" ฟิลด์ต้องไม่มีหรือว่าง

prohibited_unless:anotherfield,value,...

เว้นแต่ anotherfield จะเท่ากับ value ใดๆ ฟิลด์ต้องไม่มีหรือว่าง "ว่าง" หมายถึง:

- ค่าเป็น `null` - ค่าเป็นสตริงว่าง - ค่าเป็นอาร์เรย์ว่างหรืออ็อบเจกต์ `Countable` ว่าง - ไฟล์ที่อัปโหลดที่มี path ว่าง

prohibits:anotherfield,...

เมื่อฟิลด์มีอยู่และไม่ว่าง ฟิลด์ทั้งหมดใน anotherfield ต้องไม่มีหรือว่าง "ว่าง" หมายถึง:

- ค่าเป็น `null` - ค่าเป็นสตริงว่าง - ค่าเป็นอาร์เรย์ว่างหรืออ็อบเจกต์ `Countable` ว่าง - ไฟล์ที่อัปโหลดที่มี path ว่าง

regex:pattern

ฟิลด์ต้องตรงกับ regular expression ที่กำหนด

กฎนี้ใช้ PHP preg_match regex ต้องมีตัวคั่น เช่น 'email' => 'regex:/^.+@.+$/i'

[!WARNING]
เมื่อใช้ regex/not_regex หาก regex มี | ให้ใช้รูปแบบ array เพื่อหลีกเลี่ยงความขัดแย้งกับตัวคั่น |

required

ฟิลด์ต้องมีอยู่และไม่ว่าง "ว่าง" หมายถึง:

- ค่าเป็น `null` - ค่าเป็นสตริงว่าง - ค่าเป็นอาร์เรย์ว่างหรืออ็อบเจกต์ `Countable` ว่าง - ไฟล์ที่อัปโหลดที่มี path ว่าง

required_if:anotherfield,value,...

เมื่อ anotherfield เท่ากับ value ใดๆ ฟิลด์ต้องมีอยู่และไม่ว่าง

สำหรับเงื่อนไขที่ซับซ้อน ให้ใช้ Rule::requiredIf:

use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'role_id' => Rule::requiredIf($isAdmin),
])->validate();

Validator::make($data, [
    'role_id' => Rule::requiredIf(fn () => $isAdmin),
])->validate();

required_if_accepted:anotherfield,...

เมื่อ anotherfield เป็น "yes", "on", 1, "1", true หรือ "true" ฟิลด์ต้องมีอยู่และไม่ว่าง

required_if_declined:anotherfield,...

เมื่อ anotherfield เป็น "no", "off", 0, "0", false หรือ "false" ฟิลด์ต้องมีอยู่และไม่ว่าง

required_unless:anotherfield,value,...

เว้นแต่ anotherfield จะเท่ากับ value ใดๆ ฟิลด์ต้องมีอยู่และไม่ว่าง หาก value เป็น null (เช่น required_unless:name,null) ฟิลด์อาจว่างได้เฉพาะเมื่อฟิลด์เปรียบเทียบเป็น null หรือไม่มี

required_with:foo,bar,...

เมื่อฟิลด์ที่ระบุใดๆ มีอยู่และไม่ว่าง ฟิลด์ต้องมีอยู่และไม่ว่าง

required_with_all:foo,bar,...

เมื่อฟิลด์ที่ระบุทั้งหมดมีอยู่และไม่ว่าง ฟิลด์ต้องมีอยู่และไม่ว่าง

required_without:foo,bar,...

เมื่อฟิลด์ที่ระบุใดๆ ว่างหรือไม่มี ฟิลด์ต้องมีอยู่และไม่ว่าง

required_without_all:foo,bar,...

เมื่อฟิลด์ที่ระบุทั้งหมดว่างหรือไม่มี ฟิลด์ต้องมีอยู่และไม่ว่าง

required_array_keys:foo,bar,...

ฟิลด์ต้องเป็นอาร์เรย์และต้องมีคีย์ที่ระบุอย่างน้อยหนึ่งคีย์

sometimes

ใช้กฎการตรวจสอบถัดไปเฉพาะเมื่อฟิลด์มีอยู่ มักใช้สำหรับฟิลด์ "ตัวเลือกแต่ต้องถูกต้องเมื่อมี":

Validator::make($data, [
    'nickname' => 'sometimes|string|max:20',
])->validate();

same:field

ฟิลด์ต้องเหมือนกับ field

size:value

ขนาดฟิลด์ต้องเท่ากับ value ที่กำหนด สำหรับสตริง: จำนวนอักขระ สำหรับตัวเลข: จำนวนเต็มที่ระบุ (ใช้กับ numeric หรือ integer) สำหรับอาร์เรย์: จำนวนองค์ประกอบ สำหรับไฟล์: ขนาดเป็น KB ตัวอย่าง:

Validator::make($data, [
    'title' => 'size:12',
    'seats' => 'integer|size:10',
    'tags' => 'array|size:5',
    'image' => 'file|size:512',
])->validate();

starts_with:foo,bar,...

ฟิลด์ต้องขึ้นต้นด้วยค่าที่ระบุอย่างน้อยหนึ่งค่า

string

ฟิลด์ต้องเป็นสตริง เพื่ออนุญาต null ให้ใช้ร่วมกับ nullable

timezone

ฟิลด์ต้องเป็นตัวระบุ timezone ที่ถูกต้อง (จาก DateTimeZone::listIdentifiers) สามารถส่งพารามิเตอร์ที่เมธอดนั้นรองรับได้:

Validator::make($data, [
    'timezone' => 'required|timezone:all',
])->validate();

Validator::make($data, [
    'timezone' => 'required|timezone:Africa',
])->validate();

Validator::make($data, [
    'timezone' => 'required|timezone:per_country,US',
])->validate();

unique:table,column

ฟิลด์ต้องไม่ซ้ำในตารางที่ระบุ

ระบุชื่อตาราง/คอลัมน์ที่กำหนดเอง:

สามารถระบุชื่อคลาส model โดยตรงได้:

Validator::make($data, [
    'email' => 'unique:app\model\User,email_address',
])->validate();

สามารถระบุชื่อคอลัมน์ได้ (ใช้ชื่อฟิลด์โดยค่าเริ่มต้นเมื่อไม่ระบุ):

Validator::make($data, [
    'email' => 'unique:users,email_address',
])->validate();

ระบุการเชื่อมต่อฐานข้อมูล:

Validator::make($data, [
    'email' => 'unique:connection.users,email_address',
])->validate();

ข้าม ID ที่ระบุ:

use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'email' => [
        'required',
        Rule::unique('users')->ignore($user->id),
    ],
])->validate();

[!WARNING]
ignore ไม่ควรรับอินพุตจากผู้ใช้ ใช้เฉพาะ ID ไม่ซ้ำที่ระบบสร้าง (auto-increment ID หรือ model UUID) เท่านั้น มิฉะนั้นอาจมีความเสี่ยง SQL injection

สามารถส่งอินสแตนซ์ model ได้:

use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'email' => [
        Rule::unique('users')->ignore($user),
    ],
])->validate();

หากคีย์หลักไม่ใช่ id ให้ระบุชื่อคีย์หลัก:

use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'email' => [
        Rule::unique('users')->ignore($user->id, 'user_id'),
    ],
])->validate();

โดยค่าเริ่มต้นใช้ชื่อฟิลด์เป็นคอลัมน์ unique สามารถระบุชื่อคอลัมน์ได้:

use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'email' => [
        Rule::unique('users', 'email_address')->ignore($user->id),
    ],
])->validate();

เพิ่มเงื่อนไขเพิ่มเติม:

use Illuminate\Database\Query\Builder;
use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'email' => [
        Rule::unique('users')->where(
            fn (Builder $query) => $query->where('account_id', 1)
        ),
    ],
])->validate();

ข้ามเรคอร์ดที่ลบแบบ soft-delete:

use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'email' => [Rule::unique('users')->withoutTrashed()],
])->validate();

หากคอลัมน์ soft delete ไม่ใช่ deleted_at:

use support\validation\Rule;
use support\validation\Validator;

Validator::make($data, [
    'email' => [Rule::unique('users')->withoutTrashed('was_deleted_at')],
])->validate();

uppercase

ฟิลด์ต้องเป็นตัวพิมพ์ใหญ่

url

ฟิลด์ต้องเป็น URL ที่ถูกต้อง

สามารถระบุโปรโตคอลที่อนุญาตได้:

Validator::make($data, [
    'url' => 'url:http,https',
    'game' => 'url:minecraft,steam',
])->validate();

ulid

ฟิลด์ต้องเป็น ULID ที่ถูกต้อง

uuid

ฟิลด์ต้องเป็น RFC 9562 UUID ที่ถูกต้อง (เวอร์ชัน 1, 3, 4, 5, 6, 7 หรือ 8)

สามารถระบุเวอร์ชันได้:

Validator::make($data, [
    'uuid' => 'uuid:4',
])->validate();

ตัวตรวจสอบ top-think/think-validate

คำอธิบาย

ตัวตรวจสอบอย่างเป็นทางการของ ThinkPHP

URL โปรเจกต์

https://github.com/top-think/think-validate

การติดตั้ง

composer require topthink/think-validate

เริ่มต้นอย่างรวดเร็ว

สร้าง app/index/validate/User.php

<?php
namespace app\index\validate;

use think\Validate;

class User extends Validate
{
    protected $rule =   [
        'name'  => 'require|max:25',
        'age'   => 'number|between:1,120',
        'email' => 'email',    
    ];

    protected $message  =   [
        'name.require' => 'Name is required',
        'name.max'     => 'Name cannot exceed 25 characters',
        'age.number'   => 'Age must be a number',
        'age.between'  => 'Age must be between 1 and 120',
        'email'        => 'Invalid email format',    
    ];

}

การใช้งาน

$data = [
    'name'  => 'thinkphp',
    'email' => 'thinkphp@qq.com',
];

$validate = new \app\index\validate\User;

if (!$validate->check($data)) {
    var_dump($validate->getError());
}

หมายเหตุ
webman ไม่รองรับเมธอด Validate::rule() ของ think-validate

ตัวตรวจสอบ workerman/validation

คำอธิบาย

โปรเจกต์นี้เป็นเวอร์ชันที่แปลเป็นภาษาท้องถิ่นของ https://github.com/Respect/Validation

URL โปรเจกต์

https://github.com/walkor/validation

การติดตั้ง

composer require workerman/validation

เริ่มต้นอย่างรวดเร็ว

<?php
namespace app\controller;

use support\Request;
use Respect\Validation\Validator as v;
use support\Db;

class IndexController
{
    public function index(Request $request)
    {
        $data = v::input($request->post(), [
            'nickname' => v::length(1, 64)->setName('Nickname'),
            'username' => v::alnum()->length(5, 64)->setName('Username'),
            'password' => v::length(5, 64)->setName('Password')
        ]);
        Db::table('user')->insert($data);
        return json(['code' => 0, 'msg' => 'ok']);
    }
}  

เข้าถึงผ่าน jQuery

  $.ajax({
      url : 'http://127.0.0.1:8787',
      type : "post",
      dataType:'json',
      data : {nickname:'Tom', username:'tom cat', password: '123456'}
  });

ผลลัพธ์:

{"code":500,"msg":"Username may only contain letters (a-z) and numbers (0-9)"}

คำอธิบาย:

v::input(array $input, array $rules) ตรวจสอบและรวบรวมข้อมูล หากการตรวจสอบล้มเหลว จะโยน Respect\Validation\Exceptions\ValidationException เมื่อสำเร็จจะคืนค่าข้อมูลที่ตรวจสอบแล้ว (array)

หากโค้ดธุรกิจไม่จับข้อยกเว้นการตรวจสอบ เฟรมเวิร์ก webman จะจับและคืนค่า JSON (เช่น {"code":500, "msg":"xxx"}) หรือหน้าข้อยกเว้นปกติตาม HTTP headers หากรูปแบบการตอบกลับไม่ตรงตามความต้องการ สามารถจับ ValidationException และคืนค่าข้อมูลที่กำหนดเองได้ ดังตัวอย่างด้านล่าง:

<?php
namespace app\controller;

use support\Request;
use Respect\Validation\Validator as v;
use Respect\Validation\Exceptions\ValidationException;

class IndexController
{
    public function index(Request $request)
    {
        try {
            $data = v::input($request->post(), [
                'username' => v::alnum()->length(5, 64)->setName('Username'),
                'password' => v::length(5, 64)->setName('Password')
            ]);
        } catch (ValidationException $e) {
            return json(['code' => 500, 'msg' => $e->getMessage()]);
        }
        return json(['code' => 0, 'msg' => 'ok', 'data' => $data]);
    }
}

คู่มือตัวตรวจสอบ

use Respect\Validation\Validator as v;

// การตรวจสอบกฎเดียว
$number = 123;
v::numericVal()->validate($number); // true

// การตรวจสอบแบบเชื่อมต่อ
$usernameValidator = v::alnum()->noWhitespace()->length(1, 15);
$usernameValidator->validate('alganet'); // true

// รับเหตุผลการล้มเหลวครั้งแรก
try {
    $usernameValidator->setName('Username')->check('alg  anet');
} catch (ValidationException $exception) {
    echo $exception->getMessage(); // Username may only contain letters (a-z) and numbers (0-9)
}

// รับเหตุผลการล้มเหลวทั้งหมด
try {
    $usernameValidator->setName('Username')->assert('alg  anet');
} catch (ValidationException $exception) {
    echo $exception->getFullMessage();
    // Will print
    // -  Username must satisfy the following rules
    //     - Username may only contain letters (a-z) and numbers (0-9)
    //     - Username must not contain whitespace

    var_export($exception->getMessages());
    // Will print
    // array (
    //   'alnum' => 'Username may only contain letters (a-z) and numbers (0-9)',
    //   'noWhitespace' => 'Username must not contain whitespace',
    // )
}

// ข้อความข้อผิดพลาดที่กำหนดเอง
try {
    $usernameValidator->setName('Username')->assert('alg  anet');
} catch (ValidationException $exception) {
    var_export($exception->getMessages([
        'alnum' => 'Username may only contain letters and numbers',
        'noWhitespace' => 'Username must not contain spaces',
        'length' => 'length satisfies the rule, so this will not be shown'
    ]));
    // Will print 
    // array(
    //    'alnum' => 'Username may only contain letters and numbers',
    //    'noWhitespace' => 'Username must not contain spaces'
    // )
}

// ตรวจสอบอ็อบเจกต์
$user = new stdClass;
$user->name = 'Alexandre';
$user->birthdate = '1987-07-01';
$userValidator = v::attribute('name', v::stringType()->length(1, 32))
                ->attribute('birthdate', v::date()->minAge(18));
$userValidator->validate($user); // true

// ตรวจสอบอาร์เรย์
$data = [
    'parentKey' => [
        'field1' => 'value1',
        'field2' => 'value2'
        'field3' => true,
    ]
];
v::key(
    'parentKey',
    v::key('field1', v::stringType())
        ->key('field2', v::stringType())
        ->key('field3', v::boolType())
    )
    ->assert($data); // Can also use check() or validate()

// การตรวจสอบตัวเลือก
v::alpha()->validate(''); // false 
v::alpha()->validate(null); // false 
v::optional(v::alpha())->validate(''); // true
v::optional(v::alpha())->validate(null); // true

// กฎปฏิเสธ
v::not(v::intVal())->validate(10); // false

ความแตกต่างระหว่างเมธอด Validator validate() check() assert()

validate() คืนค่า boolean ไม่โยนข้อยกเว้น

check() โยนข้อยกเว้นเมื่อการตรวจสอบล้มเหลว รับเหตุผลการล้มเหลวครั้งแรกผ่าน $exception->getMessage()

assert() โยนข้อยกเว้นเมื่อการตรวจสอบล้มเหลว รับเหตุผลการล้มเหลวทั้งหมดผ่าน $exception->getFullMessage()

กฎการตรวจสอบทั่วไป

Alnum() เฉพาะตัวอักษรและตัวเลข

Alpha() เฉพาะตัวอักษร

ArrayType() ประเภทอาร์เรย์

Between(mixed $minimum, mixed $maximum) ตรวจสอบว่าอินพุตอยู่ระหว่างสองค่า

BoolType() ประเภท boolean

Contains(mixed $expectedValue) ตรวจสอบว่าอินพุตมีค่าที่กำหนด

ContainsAny(array $needles) ตรวจสอบว่าอินพุตมีค่าที่กำหนดอย่างน้อยหนึ่งค่า

Digit() ตรวจสอบว่าอินพุตมีเฉพาะตัวเลข

Domain() ตรวจสอบชื่อโดเมนที่ถูกต้อง

Email() ตรวจสอบที่อยู่อีเมลที่ถูกต้อง

Extension(string $extension) ตรวจสอบนามสกุลไฟล์

FloatType() ประเภท float

IntType() ประเภท integer

Ip() ตรวจสอบที่อยู่ IP

Json() ตรวจสอบข้อมูล JSON

Length(int $min, int $max) ตรวจสอบความยาวอยู่ในช่วง

LessThan(mixed $compareTo) ตรวจสอบความยาวน้อยกว่าค่าที่กำหนด

Lowercase() ตรวจสอบตัวพิมพ์เล็ก

MacAddress() ตรวจสอบที่อยู่ MAC

NotEmpty() ตรวจสอบไม่ว่าง

NullType() ตรวจสอบ null

Number() ตรวจสอบตัวเลข

ObjectType() ตรวจสอบประเภทอ็อบเจกต์

StringType() ตรวจสอบประเภทสตริง

Url() ตรวจสอบ URL

ดู https://respect-validation.readthedocs.io/en/2.0/list-of-rules/ สำหรับกฎการตรวจสอบเพิ่มเติม

เพิ่มเติม

เยี่ยมชม https://respect-validation.readthedocs.io/en/2.0/