Otros validadores

Hay muchos validadores disponibles en composer que pueden usarse directamente, como:

webman/validation (Recomendado)

top-think/think-validate

respect/validation

Validador webman/validation

Basado en illuminate/validation, proporciona validación manual, validación por anotaciones, validación a nivel de parámetros y conjuntos de reglas reutilizables.

Instalación

composer require webman/validation

Conceptos básicos

  • Reutilización de conjuntos de reglas: Define rules, messages, attributes y scenes reutilizables extendiendo support\validation\Validator, que pueden reutilizarse tanto en validación manual como por anotaciones.
  • Validación por anotaciones (atributos) a nivel de método: Usa el atributo de PHP 8 #[Validate] para vincular la validación a los métodos del controlador.
  • Validación por anotaciones (atributos) a nivel de parámetro: Usa el atributo de PHP 8 #[Param] para vincular la validación a los parámetros de los métodos del controlador.
  • Manejo de excepciones: Lanza support\validation\ValidationException cuando falla la validación; la clase de excepción es configurable.
  • Validación en base de datos: Si la validación implica base de datos, necesitas instalar composer require webman/database.

Validación manual

Uso básico

use support\validation\Validator;

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

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

Nota
validate() lanza support\validation\ValidationException cuando falla la validación. Si prefieres no lanzar excepciones, usa el enfoque con fails() que se muestra a continuación para obtener los mensajes de error.

Mensajes y atributos personalizados

use support\validation\Validator;

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

Validator::make(
    $data,
    ['contact' => 'required|email'],
    ['contact.email' => 'Formato de email inválido'],
    ['contact' => 'Email']
)->validate();

Validar sin excepción (obtener mensajes de error)

Si prefieres no lanzar excepciones, usa fails() para comprobar y obtener los mensajes de error mediante errors() (devuelve 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
    // manejar errores...
}

Reutilización de conjuntos de reglas (validador personalizado)

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' => 'El nombre es obligatorio',
        'email.required' => 'El email es obligatorio',
        'email.email' => 'Formato de email inválido',
    ];

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

Reutilización en validación manual

use app\validation\UserValidator;

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

Uso de escenas (opcional)

scenes es una característica opcional; solo valida un subconjunto de campos cuando llamas a 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;

// Sin escena especificada -> valida todas las reglas
UserValidator::make($data)->validate();

// Escena especificada -> valida solo los campos de esa escena
UserValidator::make($data)->withScene('create')->validate();

Validación por anotaciones (nivel de método)

Reglas directas

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

class AuthController
{
    #[Validate(
        rules: [
            'email' => 'required|email',
            'password' => 'required|string|min:6',
        ],
        messages: [
            'email.required' => 'El email es obligatorio',
            'password.required' => 'La contraseña es obligatoria',
        ],
        attributes: [
            'email' => 'Email',
            'password' => 'Contraseña',
        ]
    )]
    public function login(Request $request)
    {
        return json(['code' => 0, 'msg' => 'ok']);
    }
}

Reutilizar conjuntos de reglas

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']);
    }
}

Múltiples validaciones superpuestas

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']);
    }
}

Fuente de datos de validación

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']);
    }
}

Usa el parámetro in para especificar la fuente de datos:

  • query Parámetros de consulta de la petición HTTP, desde $request->get()
  • body Cuerpo de la petición HTTP, desde $request->post()
  • path Parámetros de ruta de la petición HTTP, desde $request->route->param()

in puede ser una cadena o un array; cuando es un array, los valores se fusionan en orden y los posteriores sobrescriben a los anteriores. Cuando no se pasa in, por defecto es ['query', 'body', 'path'].

Validación a nivel de parámetro (Param)

Uso básico

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']);
    }
}

Fuente de datos de validación

De forma similar, la validación a nivel de parámetro también admite el parámetro in para especificar la fuente:

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 admite string o array

use support\validation\annotation\Param;

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

Mensajes / atributo personalizados

use support\validation\annotation\Param;

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

Reutilización de constantes de reglas

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']);
    }
}

Combinación de validación a nivel de método y de parámetro

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']);
    }
}

Inferencia automática de reglas (basada en la firma del parámetro)

Cuando se usa #[Validate] en un método, o cualquier parámetro de ese método usa #[Param], este componente infiere y completa automáticamente las reglas de validación básicas a partir de la firma de los parámetros del método, y luego las fusiona con las reglas existentes antes de validar.

Ejemplo: expansión equivalente de #[Validate]

1) Solo habilitar #[Validate] sin escribir reglas manualmente:

use support\validation\annotation\Validate;

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

Equivalente a:

use support\validation\annotation\Validate;

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

2) Solo reglas parciales escritas, el resto completado por la firma del parámetro:

use support\validation\annotation\Validate;

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

Equivalente a:

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) Valor por defecto / tipo nullable:

use support\validation\annotation\Validate;

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

Equivalente a:

use support\validation\annotation\Validate;

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

Manejo de excepciones

Excepción por defecto

El fallo de validación lanza support\validation\ValidationException por defecto, que extiende Webman\Exception\BusinessException y no registra errores.

El comportamiento de respuesta por defecto lo maneja BusinessException::render():

  • Peticiones normales: devuelve mensaje de texto, ej. token is required.
  • Peticiones JSON: devuelve respuesta JSON, ej. {"code": 422, "msg": "token is required.", "data":....}

Personalizar el manejo mediante excepción personalizada

  • Configuración global: exception en config/plugin/webman/validation/app.php

Soporte multilingüe

El componente incluye paquetes de idioma chino e inglés integrados y admite sobrescrituras del proyecto. Orden de carga:

  1. Paquete de idioma del proyecto resource/translations/{locale}/validation.php
  2. Integrado en el componente vendor/webman/validation/resources/lang/{locale}/validation.php
  3. Inglés integrado de Illuminate (respaldo)

Nota
El idioma por defecto de Webman se configura en config/translation.php, o puede cambiarse mediante locale('en');.

Ejemplo de sobrescritura local

resource/translations/zh_CN/validation.php

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

Carga automática del middleware

Tras la instalación, el componente carga automáticamente el middleware de validación mediante config/plugin/webman/validation/middleware.php; no es necesario registrarlo manualmente.

Generación por línea de comandos

Usa el comando make:validator para generar clases de validador (por defecto en el directorio app/validation).

Nota
Requiere composer require webman/console

Uso básico

  • Generar plantilla vacía
php webman make:validator UserValidator
  • Sobrescribir archivo existente
php webman make:validator UserValidator --force
php webman make:validator UserValidator -f

Generar reglas desde la estructura de la tabla

  • Especificar nombre de tabla para generar reglas base (infiere $rules desde tipo de campo/nullable/longitud etc.; excluye campos relacionados con ORM por defecto: laravel usa created_at/updated_at/deleted_at, thinkorm usa create_time/update_time/delete_time)
php webman make:validator UserValidator --table=wa_users
php webman make:validator UserValidator -t wa_users
  • Especificar conexión de base de datos (escenarios con múltiples conexiones)
php webman make:validator UserValidator --table=wa_users --database=mysql
php webman make:validator UserValidator -t wa_users -d mysql

Escenas

  • Generar escenas CRUD: create/update/delete/detail
php webman make:validator UserValidator --table=wa_users --scenes=crud
php webman make:validator UserValidator -t wa_users -s crud

La escena update incluye el campo de clave primaria (para localizar registros) más otros campos; delete/detail incluyen solo la clave primaria por defecto.

Selección de ORM (laravel (illuminate/database) vs think-orm)

  • Auto-selección (por defecto): Usa el que esté instalado/configurado; cuando ambos existen, usa illuminate por defecto
  • Forzar especificación
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

Ejemplo completo

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

Pruebas unitarias

Desde el directorio raíz de webman/validation, ejecuta:

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

Referencia de reglas de validación

Reglas de validación disponibles

[!IMPORTANT]

  • Webman Validation está basado en illuminate/validation; los nombres de las reglas coinciden con Laravel y no hay reglas específicas de Webman.
  • El middleware valida datos de $request->all() (GET+POST) fusionados con parámetros de ruta por defecto, excluyendo archivos subidos; para reglas de archivos, fusiona $request->file() en los datos manualmente, o llama a Validator::make manualmente.
  • current_password depende del guard de autenticación; exists/unique dependen de la conexión a base de datos y el query builder; estas reglas no están disponibles cuando los componentes correspondientes no están integrados.

La siguiente lista muestra todas las reglas de validación disponibles y sus propósitos:

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

El campo debe ser "yes", "on", 1, "1", true, o "true". Comúnmente usado para escenarios como verificar el acuerdo del usuario con los términos de servicio.

accepted_if:anotherfield,value,...

Cuando otro campo es igual al valor especificado, el campo debe ser "yes", "on", 1, "1", true, o "true". Comúnmente usado para escenarios de acuerdo condicional.

active_url

El campo debe tener un registro A o AAAA válido. Esta regla usa primero parse_url para extraer el hostname de la URL, luego valida con dns_get_record.

after:date

El campo debe ser un valor posterior a la fecha dada. La fecha se pasa a strtotime para convertirla en un DateTime válido:

use support\validation\Validator;

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

También puedes pasar otro nombre de campo para comparación:

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

Puedes usar el constructor fluido de la regla date:

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

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

afterToday y todayOrAfter expresan convenientemente "debe ser después de hoy" o "debe ser hoy o posterior":

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

after_or_equal:date

El campo debe ser igual o posterior a la fecha dada. Consulta after para más detalles.

Puedes usar el constructor fluido de la regla date:

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 permite especificar "cumplir cualquiera de los conjuntos de reglas". Por ejemplo, la siguiente regla significa que username debe ser una dirección de email o una cadena alfanumérica/guion bajo/guion de al menos 6 caracteres:

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

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

alpha

El campo debe ser letras Unicode (\p{L} y \p{M}).

Para permitir solo ASCII (a-z, A-Z), añade la opción ascii:

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

alpha_dash

El campo solo puede contener letras y números Unicode (\p{L}, \p{M}, \p{N}), más guion (-) y guion bajo (_) ASCII.

Para permitir solo ASCII (a-z, A-Z, 0-9), añade la opción ascii:

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

alpha_num

El campo solo puede contener letras y números Unicode (\p{L}, \p{M}, \p{N}).

Para permitir solo ASCII (a-z, A-Z, 0-9), añade la opción ascii:

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

array

El campo debe ser un array de PHP.

Cuando la regla array tiene parámetros extra, las claves del array de entrada deben estar en la lista de parámetros. En el ejemplo, la clave admin no está en la lista permitida, por lo que es inválida:

use support\validation\Validator;

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

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

Se recomienda definir explícitamente las claves de array permitidas en proyectos reales.

ascii

El campo solo puede contener caracteres ASCII de 7 bits.

bail

Detener la validación de reglas posteriores para el campo cuando la primera regla falla.

Esta regla solo afecta al campo actual. Para "detener en el primer fallo globalmente", usa el validador de Illuminate directamente y llama a stopOnFirstFailure().

before:date

El campo debe ser anterior a la fecha dada. La fecha se pasa a strtotime para convertirla en un DateTime válido. Como after, puedes pasar otro nombre de campo para comparación.

Puedes usar el constructor fluido de la regla date:

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

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

beforeToday y todayOrBefore expresan convenientemente "debe ser antes de hoy" o "debe ser hoy o anterior":

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

before_or_equal:date

El campo debe ser igual o anterior a la fecha dada. La fecha se pasa a strtotime para convertirla en un DateTime válido. Como after, puedes pasar otro nombre de campo para comparación.

Puedes usar el constructor fluido de la regla date:

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

El tamaño del campo debe estar entre min y max (inclusive). La evaluación para cadenas, números, arrays y archivos es la misma que size.

boolean

El campo debe ser convertible a booleano. Las entradas aceptables incluyen true, false, 1, 0, "1", "0".

Usa el parámetro strict para permitir solo true o false:

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

confirmed

El campo debe tener un campo coincidente {field}_confirmation. Por ejemplo, cuando el campo es password, se requiere password_confirmation.

También puedes especificar un nombre de campo de confirmación personalizado, ej. confirmed:repeat_username requiere que repeat_username coincida con el campo actual.

contains:foo,bar,...

El campo debe ser un array y debe contener todos los valores de parámetro dados. Esta regla se usa comúnmente para validación de arrays; puedes usar Rule::contains para construirla:

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

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

doesnt_contain:foo,bar,...

El campo debe ser un array y no debe contener ninguno de los valores de parámetro dados. Puedes usar Rule::doesntContain para construirla:

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

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

current_password

El campo debe coincidir con la contraseña del usuario autenticado actual. Puedes especificar el guard de autenticación como primer parámetro:

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

[!WARNING]
Esta regla depende del componente de autenticación y la configuración del guard; no uses cuando la autenticación no está integrada.

date

El campo debe ser una fecha válida (no relativa) reconocible por strtotime.

date_equals:date

El campo debe ser igual a la fecha dada. La fecha se pasa a strtotime para convertirla en un DateTime válido.

date_format:format,...

El campo debe coincidir con uno de los formatos dados. Usa date o date_format. Esta regla admite todos los formatos de DateTime de PHP.

Puedes usar el constructor fluido de la regla date:

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

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

decimal:min,max

El campo debe ser numérico con los decimales requeridos:

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

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

declined

El campo debe ser "no", "off", 0, "0", false, o "false".

declined_if:anotherfield,value,...

Cuando otro campo es igual al valor especificado, el campo debe ser "no", "off", 0, "0", false, o "false".

different:field

El campo debe ser diferente de field.

digits:value

El campo debe ser un entero con longitud value.

digits_between:min,max

El campo debe ser un entero con longitud entre min y max.

dimensions

El campo debe ser una imagen y satisfacer las restricciones de dimensiones:

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

Restricciones disponibles: min_width, max_width, min_height, max_height, width, height, ratio.

ratio es la relación de aspecto; puede expresarse como fracción o float:

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

Esta regla tiene muchos parámetros; se recomienda usar Rule::dimensions para construirla:

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

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

distinct

Al validar arrays, los valores del campo no deben estar duplicados:

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

Usa comparación flexible por defecto. Añade strict para comparación estricta:

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

Añade ignore_case para ignorar diferencias de mayúsculas/minúsculas:

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

doesnt_start_with:foo,bar,...

El campo no debe comenzar con ninguno de los valores especificados.

doesnt_end_with:foo,bar,...

El campo no debe terminar con ninguno de los valores especificados.

email

El campo debe ser una dirección de email válida. Esta regla depende de egulias/email-validator, usa RFCValidation por defecto, y puede usar otros métodos de validación:

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

Métodos de validación disponibles:

- `rfc`: `RFCValidation` - Valida el email según la especificación RFC ([RFCs soportados](https://github.com/egulias/EmailValidator?tab=readme-ov-file#supported-rfcs)). - `strict`: `NoRFCWarningsValidation` - Falla en advertencias RFC (ej. punto final o puntos consecutivos). - `dns`: `DNSCheckValidation` - Comprueba si el dominio tiene registros MX válidos. - `spoof`: `SpoofCheckValidation` - Previene caracteres Unicode homógrafos o de suplantación. - `filter`: `FilterEmailValidation` - Valida usando `filter_var` de PHP. - `filter_unicode`: `FilterEmailValidation::unicode()` - Validación con `filter_var` permitiendo Unicode.

Puedes usar el constructor fluido de reglas:

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

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

[!WARNING]
dns y spoof requieren la extensión PHP intl.

encoding:encoding_type

El campo debe coincidir con la codificación de caracteres especificada. Esta regla usa mb_check_encoding para detectar la codificación del archivo o cadena. Puede usarse con el constructor de reglas de archivo:

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,...

El campo debe terminar con uno de los valores especificados.

enum

Enum es una regla basada en clase para validar que el valor del campo es un valor enum válido. Pasa el nombre de la clase enum al construir. Para valores primitivos, usa Backed Enum:

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

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

Usa only/except para restringir los valores 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();

Usa when para restricciones condicionales:

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

El campo será excluido de los datos devueltos por validate/validated.

exclude_if:anotherfield,value

Cuando anotherfield es igual a value, el campo será excluido de los datos devueltos por validate/validated.

Para condiciones complejas, usa 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

A menos que anotherfield sea igual a value, el campo será excluido de los datos devueltos por validate/validated. Si value es null (ej. exclude_unless:name,null), el campo solo se mantiene cuando el campo de comparación es null o está ausente.

exclude_with:anotherfield

Cuando anotherfield existe, el campo será excluido de los datos devueltos por validate/validated.

exclude_without:anotherfield

Cuando anotherfield no existe, el campo será excluido de los datos devueltos por validate/validated.

exists:table,column

El campo debe existir en la tabla de base de datos especificada.

Uso básico de la regla Exists

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

Cuando column no se especifica, se usa el nombre del campo por defecto. Así que este ejemplo valida si la columna state existe en la tabla states.

Especificar un nombre de columna personalizado

Añade el nombre de la columna después del nombre de la tabla:

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

Para especificar una conexión de base de datos, prefija el nombre de la tabla con el nombre de la conexión:

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

También puedes pasar un nombre de clase de modelo; el framework resolverá el nombre de la tabla:

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

Para condiciones de consulta personalizadas, usa el constructor 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();

También puedes especificar el nombre de la columna directamente en Rule::exists:

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

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

Para validar que un conjunto de valores exista, combina con la regla array:

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

Cuando tanto array como exists están presentes, una sola consulta valida todos los valores.

extensions:foo,bar,...

Valida que la extensión del archivo subido esté en la lista permitida:

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

[!WARNING]
No confíes solo en la extensión para validar el tipo de archivo; usa junto con mimes o mimetypes.

file

El campo debe ser un archivo subido correctamente.

filled

Cuando el campo existe, su valor no debe estar vacío.

gt:field

El campo debe ser mayor que el field o value dado. Ambos campos deben tener el mismo tipo. La evaluación para cadenas, números, arrays y archivos es la misma que size.

gte:field

El campo debe ser mayor o igual que el field o value dado. Ambos campos deben tener el mismo tipo. La evaluación para cadenas, números, arrays y archivos es la misma que size.

hex_color

El campo debe ser un valor de color hexadecimal válido.

image

El campo debe ser una imagen (jpg, jpeg, png, bmp, gif o webp).

[!WARNING]
SVG no está permitido por defecto debido al riesgo de XSS. Para permitirlo, añade allow_svg: image:allow_svg.

in:foo,bar,...

El campo debe estar en la lista de valores dada. Puedes usar Rule::in para construirla:

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

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

Cuando se combina con la regla array, cada valor del array de entrada debe estar en la lista 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.*

El campo debe existir en la lista de valores de anotherfield.

in_array_keys:value.*

El campo debe ser un array y debe contener al menos uno de los valores dados como clave:

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

integer

El campo debe ser un entero.

Usa el parámetro strict para requerir que el tipo del campo sea entero; los enteros en forma de cadena serán inválidos:

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

[!WARNING]
Esta regla solo valida si pasa el FILTER_VALIDATE_INT de PHP; para tipos numéricos estrictos, usa junto con numeric.

ip

El campo debe ser una dirección IP válida.

ipv4

El campo debe ser una dirección IPv4 válida.

ipv6

El campo debe ser una dirección IPv6 válida.

json

El campo debe ser una cadena JSON válida.

lt:field

El campo debe ser menor que el field dado. Ambos campos deben tener el mismo tipo. La evaluación para cadenas, números, arrays y archivos es la misma que size.

lte:field

El campo debe ser menor o igual que el field dado. Ambos campos deben tener el mismo tipo. La evaluación para cadenas, números, arrays y archivos es la misma que size.

lowercase

El campo debe estar en minúsculas.

list

El campo debe ser un array de lista. Las claves del array de lista deben ser números consecutivos desde 0 hasta count($array) - 1.

mac_address

El campo debe ser una dirección MAC válida.

max:value

El campo debe ser menor o igual a value. La evaluación para cadenas, números, arrays y archivos es la misma que size.

max_digits:value

El campo debe ser un entero con longitud que no exceda value.

mimetypes:text/plain,...

Valida que el tipo MIME del archivo esté en la lista:

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

El tipo MIME se determina leyendo el contenido del archivo y puede diferir del MIME proporcionado por el cliente.

mimes:foo,bar,...

Valida que el tipo MIME del archivo corresponda a la extensión dada:

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

Aunque los parámetros son extensiones, esta regla lee el contenido del archivo para determinar el MIME. Mapeo extensión-a-MIME:

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

Tipos MIME y extensiones

Esta regla no valida que la "extensión del archivo" coincida con el "MIME real". Por ejemplo, mimes:png trata photo.txt con contenido PNG como válido. Para validar la extensión, usa extensions.

min:value

El campo debe ser mayor o igual a value. La evaluación para cadenas, números, arrays y archivos es la misma que size.

min_digits:value

El campo debe ser un entero con longitud no menor a value.

multiple_of:value

El campo debe ser un múltiplo de value.

missing

El campo no debe existir en los datos de entrada.

missing_if:anotherfield,value,...

Cuando anotherfield es igual a cualquier value, el campo no debe existir.

missing_unless:anotherfield,value

A menos que anotherfield sea igual a cualquier value, el campo no debe existir.

missing_with:foo,bar,...

Cuando existe cualquier campo especificado, el campo no debe existir.

missing_with_all:foo,bar,...

Cuando existen todos los campos especificados, el campo no debe existir.

not_in:foo,bar,...

El campo no debe estar en la lista de valores dada. Puedes usar Rule::notIn para construirla:

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

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

not_regex:pattern

El campo no debe coincidir con la expresión regular dada.

Esta regla usa preg_match de PHP. La regex debe tener delimitadores, ej. 'email' => 'not_regex:/^.+$/i'.

[!WARNING]
Al usar regex/not_regex, si la regex contiene |, usa la forma array para evitar conflicto con el separador |.

nullable

El campo puede ser null.

numeric

El campo debe ser numérico.

Usa el parámetro strict para permitir solo tipos integer o float; las cadenas numéricas serán inválidas:

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

present

El campo debe existir en los datos de entrada.

present_if:anotherfield,value,...

Cuando anotherfield es igual a cualquier value, el campo debe existir.

present_unless:anotherfield,value

A menos que anotherfield sea igual a cualquier value, el campo debe existir.

present_with:foo,bar,...

Cuando existe cualquier campo especificado, el campo debe existir.

present_with_all:foo,bar,...

Cuando existen todos los campos especificados, el campo debe existir.

prohibited

El campo debe estar ausente o vacío. "Vacío" significa:

- El valor es `null`. - El valor es cadena vacía. - El valor es array vacío u objeto Countable vacío. - Archivo subido con ruta vacía.

prohibited_if:anotherfield,value,...

Cuando anotherfield es igual a cualquier value, el campo debe estar ausente o vacío. "Vacío" significa:

- El valor es `null`. - El valor es cadena vacía. - El valor es array vacío u objeto Countable vacío. - Archivo subido con ruta vacía.

Para condiciones complejas, usa 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,...

Cuando anotherfield es "yes", "on", 1, "1", true, o "true", el campo debe estar ausente o vacío.

prohibited_if_declined:anotherfield,...

Cuando anotherfield es "no", "off", 0, "0", false, o "false", el campo debe estar ausente o vacío.

prohibited_unless:anotherfield,value,...

A menos que anotherfield sea igual a cualquier value, el campo debe estar ausente o vacío. "Vacío" significa:

- El valor es `null`. - El valor es cadena vacía. - El valor es array vacío u objeto Countable vacío. - Archivo subido con ruta vacía.

prohibits:anotherfield,...

Cuando el campo existe y no está vacío, todos los campos en anotherfield deben estar ausentes o vacíos. "Vacío" significa:

- El valor es `null`. - El valor es cadena vacía. - El valor es array vacío u objeto Countable vacío. - Archivo subido con ruta vacía.

regex:pattern

El campo debe coincidir con la expresión regular dada.

Esta regla usa preg_match de PHP. La regex debe tener delimitadores, ej. 'email' => 'regex:/^.+@.+$/i'.

[!WARNING]
Al usar regex/not_regex, si la regex contiene |, usa la forma array para evitar conflicto con el separador |.

required

El campo debe existir y no estar vacío. "Vacío" significa:

- El valor es `null`. - El valor es cadena vacía. - El valor es array vacío u objeto Countable vacío. - Archivo subido con ruta vacía.

required_if:anotherfield,value,...

Cuando anotherfield es igual a cualquier value, el campo debe existir y no estar vacío.

Para condiciones complejas, usa 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,...

Cuando anotherfield es "yes", "on", 1, "1", true, o "true", el campo debe existir y no estar vacío.

required_if_declined:anotherfield,...

Cuando anotherfield es "no", "off", 0, "0", false, o "false", el campo debe existir y no estar vacío.

required_unless:anotherfield,value,...

A menos que anotherfield sea igual a cualquier value, el campo debe existir y no estar vacío. Si value es null (ej. required_unless:name,null), el campo puede estar vacío solo cuando el campo de comparación es null o está ausente.

required_with:foo,bar,...

Cuando existe y no está vacío cualquier campo especificado, el campo debe existir y no estar vacío.

required_with_all:foo,bar,...

Cuando existen y no están vacíos todos los campos especificados, el campo debe existir y no estar vacío.

required_without:foo,bar,...

Cuando cualquier campo especificado está vacío o ausente, el campo debe existir y no estar vacío.

required_without_all:foo,bar,...

Cuando todos los campos especificados están vacíos o ausentes, el campo debe existir y no estar vacío.

required_array_keys:foo,bar,...

El campo debe ser un array y debe contener al menos las claves especificadas.

sometimes

Aplicar reglas de validación posteriores solo cuando el campo existe. Comúnmente usado para campos "opcionales pero deben ser válidos cuando están presentes":

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

same:field

El campo debe ser igual a field.

size:value

El tamaño del campo debe ser igual al value dado. Para cadenas: número de caracteres; para números: entero especificado (usar con numeric o integer); para arrays: número de elementos; para archivos: tamaño en KB. Ejemplo:

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

starts_with:foo,bar,...

El campo debe comenzar con uno de los valores especificados.

string

El campo debe ser una cadena. Para permitir null, usa junto con nullable.

timezone

El campo debe ser un identificador de zona horaria válido (de DateTimeZone::listIdentifiers). Puedes pasar parámetros soportados por ese método:

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

El campo debe ser único en la tabla especificada.

Especificar nombre de tabla/columna personalizado:

Puedes especificar directamente el nombre de la clase del modelo:

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

Puedes especificar el nombre de la columna (por defecto usa el nombre del campo cuando no se especifica):

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

Especificar conexión de base de datos:

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

Ignorar ID especificado:

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

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

[!WARNING]
ignore no debe recibir entrada del usuario; usa solo IDs únicos generados por el sistema (ID autoincremental o UUID del modelo), de lo contrario puede existir riesgo de inyección SQL.

También puedes pasar una instancia del modelo:

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

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

Si la clave primaria no es id, especifica el nombre de la clave primaria:

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

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

Por defecto usa el nombre del campo como columna única; también puedes especificar el nombre de la columna:

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

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

Añadir condiciones extra:

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();

Ignorar registros con borrado lógico:

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

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

Si la columna de borrado lógico no es deleted_at:

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

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

uppercase

El campo debe estar en mayúsculas.

url

El campo debe ser una URL válida.

Puedes especificar los protocolos permitidos:

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

ulid

El campo debe ser un ULID válido.

uuid

El campo debe ser un UUID RFC 9562 válido (versión 1, 3, 4, 5, 6, 7 u 8).

Puedes especificar la versión:

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

Validador top-think/think-validate

Descripción

Validador oficial de ThinkPHP

URL del proyecto

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

Instalación

composer require topthink/think-validate

Inicio rápido

Crear 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' => 'El nombre es obligatorio',
        'name.max'     => 'El nombre no puede exceder 25 caracteres',
        'age.number'   => 'La edad debe ser un número',
        'age.between'  => 'La edad debe estar entre 1 y 120',
        'email'        => 'Formato de email inválido',    
    ];

}

Uso

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

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

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

Nota
webman no soporta el método Validate::rule() de think-validate

Validador workerman/validation

Descripción

Este proyecto es una versión localizada de https://github.com/Respect/Validation

URL del proyecto

https://github.com/walkor/validation

Instalación

composer require workerman/validation

Inicio rápido

<?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']);
    }
}  

Acceso vía jQuery

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

Resultado:

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

Explicación:

v::input(array $input, array $rules) valida y recopila datos. Si la validación falla, lanza Respect\Validation\Exceptions\ValidationException; si tiene éxito devuelve los datos validados (array).

Si el código de negocio no captura la excepción de validación, el framework webman la capturará y devolverá JSON (como {"code":500, "msg":"xxx"}) o una página de excepción normal según los encabezados HTTP. Si el formato de respuesta no cumple tus necesidades, puedes capturar ValidationException y devolver datos personalizados, como en el ejemplo siguiente:

<?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]);
    }
}

Guía del validador

use Respect\Validation\Validator as v;

// Validación de regla única
$number = 123;
v::numericVal()->validate($number); // true

// Validación encadenada
$usernameValidator = v::alnum()->noWhitespace()->length(1, 15);
$usernameValidator->validate('alganet'); // true

// Obtener primera razón de fallo de validación
try {
    $usernameValidator->setName('Username')->check('alg  anet');
} catch (ValidationException $exception) {
    echo $exception->getMessage(); // Username may only contain letters (a-z) and numbers (0-9)
}

// Obtener todas las razones de fallo de validación
try {
    $usernameValidator->setName('Username')->assert('alg  anet');
} catch (ValidationException $exception) {
    echo $exception->getFullMessage();
    // Imprimirá
    // -  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());
    // Imprimirá
    // array (
    //   'alnum' => 'Username may only contain letters (a-z) and numbers (0-9)',
    //   'noWhitespace' => 'Username must not contain whitespace',
    // )
}

// Mensajes de error personalizados
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'
    ]));
    // Imprimirá 
    // array(
    //    'alnum' => 'Username may only contain letters and numbers',
    //    'noWhitespace' => 'Username must not contain spaces'
    // )
}

// Validar objeto
$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

// Validar array
$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); // También puede usar check() o validate()

// Validación opcional
v::alpha()->validate(''); // false 
v::alpha()->validate(null); // false 
v::optional(v::alpha())->validate(''); // true
v::optional(v::alpha())->validate(null); // true

// Regla de negación
v::not(v::intVal())->validate(10); // false

Diferencia entre los métodos del validador validate() check() assert()

validate() devuelve booleano, no lanza excepción

check() lanza excepción cuando falla la validación; obtén la primera razón de fallo mediante $exception->getMessage()

assert() lanza excepción cuando falla la validación; obtén todas las razones de fallo mediante $exception->getFullMessage()

Reglas de validación comunes

Alnum() Solo letras y números

Alpha() Solo letras

ArrayType() Tipo array

Between(mixed $minimum, mixed $maximum) Valida que la entrada esté entre dos valores.

BoolType() Tipo booleano

Contains(mixed $expectedValue) Valida que la entrada contenga cierto valor

ContainsAny(array $needles) Valida que la entrada contenga al menos un valor definido

Digit() Valida que la entrada contenga solo dígitos

Domain() Valida nombre de dominio válido

Email() Valida dirección de email válida

Extension(string $extension) Valida extensión de archivo

FloatType() Tipo float

IntType() Tipo entero

Ip() Valida dirección IP

Json() Valida datos JSON

Length(int $min, int $max) Valida que la longitud esté dentro del rango

LessThan(mixed $compareTo) Valida que la longitud sea menor que el valor dado

Lowercase() Minúsculas

MacAddress() Dirección MAC

NotEmpty() No vacío

NullType() Null

Number() Número

ObjectType() Tipo objeto

StringType() Tipo cadena

Url() URL

Consulta https://respect-validation.readthedocs.io/en/2.0/list-of-rules/ para más reglas de validación.

Más

Visita https://respect-validation.readthedocs.io/en/2.0/