mewtonium/vanguard 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

mewtonium/vanguard

Composer 安装命令:

composer require mewtonium/vanguard

包简介

A simple validation library using PHP attributes.

README 文档

README

Caution

🛑 This package is intended for demo purposes only and is not suitable for production use. Please do not use it in live or production environments. 🛑

Vanguard is a simple, attribute-based validation library for PHP, providing a clean and easy way to validate data using attributes on class properties.

Features

  • Simple attribute-based validation.
  • Dependency-free - no external libraries required.
  • Supports common validation rules, with more to be added in future.
    • Comparison and range-based rules (Between, GreaterOrEqual, GreaterThan, LessOrEqual, LessThan) also validate strings as dates when applicable.
    • Equal can check strings as either a date string, or a standard value.
    • Scalar rules such as Url, Numeric, Integer, Boolean, Alpha, AlphaNum and Regex.
  • Write your own rules by implementing a simple contract — see Writing Custom Rules.
  • Supports for a custom error message on any rule.

Installation

composer require mewtonium/vanguard

Usage

Add the Vanguard trait to any class, add a few Rule attributes to properties and call validate() - simple!

<?php

use App\Validation\Rules\Uppercase;
use Mewtonium\Vanguard\Rules\In;
use Mewtonium\Vanguard\Rules\MaxLength;
use Mewtonium\Vanguard\Rules\MinLength;
use Mewtonium\Vanguard\Rules\Email;
use Mewtonium\Vanguard\Rules\Between;
use Mewtonium\Vanguard\Rules\Required;
use Mewtonium\Vanguard\Vanguard;

class AccountSignupForm
{
    use Vanguard;

    public function __construct(
        #[Required, MinLength(2), MaxLength(255)]
        protected string $firstName,

        #[Required(message: 'Please provide your last name.'), MinLength(2), MaxLength(255)]
        protected string $lastName,

        #[Required, Between(18, 99)]
        protected int $age,
        
        #[Required, Email]
        protected string $email,
        
        #[Required, In(['GB', 'FR', 'DE', 'ES', 'IT', 'IE', 'JP', 'ZH']), Uppercase]
        protected string $country,
        
        #[Required, GreaterOrEqual('2025-01-01')]
        protected string $date,
    ) {
        //
    }
}

$data = [
    'firstName' => 'Joe',
    'lastName' => '',
    'age' => 17,
    'email' => 'joe.bloggs',
    'country' => 'ch',
    'date' => '2024-01-01',
];

$form = new AccountSignupForm(...$data);
$form->validate();

Validation Rules

Note: Vanguard performs validation only. It does not sanitise or modify your input data in any way — ensure you handle sanitisation separately, if needed.

Here are all the currently supported validation rules:

Alpha

Validates that the value contains letters only.

use Mewtonium\Vanguard\Rules\Alpha;

#[Alpha]
public string $name;

AlphaNum

Validates that the value contains letters and numbers only.

use Mewtonium\Vanguard\Rules\AlphaNum;

#[AlphaNum]
public string $username;

Between

Validates whether the value lies within the inclusive range of min and max.

use Mewtonium\Vanguard\Rules\Between;

#[Between(1, 100)]
public int $numbers;

#[Between('2020-01-01', '2030-01-01')] 
public string $date;

Boolean

Validates that the value is a boolean. Accepts true, false, 1, 0, '1' and '0'.

use Mewtonium\Vanguard\Rules\Boolean;

#[Boolean]
public mixed $active;

Email

Validates that the value is a valid email address using filter_var.

use Mewtonium\Vanguard\Rules\Email;

#[Email]
public string $email;

Equal

Validates if the value is equal to the given value. If both are strings and resemble date strings, it compares them as dates.

use Mewtonium\Vanguard\Rules\Equal;

#[Equal(30)]
public int $age;

#[Equal('2025-01-01')]
public string $date;

GreaterOrEqual

Validates if the value is greater than or equal to the given value.

use Mewtonium\Vanguard\Rules\GreaterOrEqual;

#[GreaterOrEqual(30)]
public int $age;

#[GreaterOrEqual('2025-01-01')] 
public string $date;

GreaterThan

Validates if the value is strictly greater than the given value.

use Mewtonium\Vanguard\Rules\GreaterThan;

#[GreaterThan(30)]
public int $age;

#[GreaterThan('2025-01-01')] 
public string $date;

In

Validate that the value exists within a predefined list of values.

use Mewtonium\Vanguard\Rules\In;

#[In(['GB', 'FR', 'DE'])]
public string $country;

Integer

Validates that the value is an integer (or an integer-like string). Booleans are rejected.

use Mewtonium\Vanguard\Rules\Integer;

#[Integer]
public mixed $count;

LessOrEqual

Checks if the value is less than or equal to the given value.

use Mewtonium\Vanguard\Rules\LessOrEqual;

#[LessOrEqual(30)]
public int $age;

#[LessOrEqual('2030-01-01')] 
public string $date;

LessThan

Validates if the value is strictly less than the given value.

use Mewtonium\Vanguard\Rules\LessThan;

#[LessThan(30)]
public int $age;

#[LessThan('2030-01-01')] 
public string $date;

MaxLength

Validates that a string or array has no more than the given number of characters or items.

use Mewtonium\Vanguard\Rules\MaxLength;

#[MaxLength(255)]
public string $url;

#[MaxLength(10)]
public array $data;

MinLength

Validates that a string or array has at least the given number of characters or items.

use Mewtonium\Vanguard\Rules\MinLength;

#[MinLength(3)]
public string $name;

#[MinLength(3)]
public array $data;

Numeric

Validates that the value is numeric (an integer, float, or numeric string).

use Mewtonium\Vanguard\Rules\Numeric;

#[Numeric]
public mixed $amount;

Regex

Validates that the value matches a given PCRE pattern.

Note: The pattern is supplied by you in the form definition — never derive it from end-user input. Authoring a pattern vulnerable to catastrophic backtracking (ReDoS) is your responsibility.

use Mewtonium\Vanguard\Rules\Regex;

#[Regex('/^[A-Z]{2}-\d{3}$/')]
public string $reference;

Required

Validate that the value is not null, an empty string, or an empty array.

use Mewtonium\Vanguard\Rules\Required;

#[Required]
public string $name;

Url

Validates that the value is a valid URL using filter_var.

use Mewtonium\Vanguard\Rules\Url;

#[Url]
public string $website;

Writing Custom Rules

Write your own rule by extending the abstract BaseRule class and adding the #[\Attribute(\Attribute::TARGET_PROPERTY)] attribute. BaseRule gives you the injected $field/$value properties and the custom-message plumbing — you only implement passes() and the default message():

use Mewtonium\Vanguard\Rules\BaseRule;

#[\Attribute(\Attribute::TARGET_PROPERTY)]
final class Uppercase extends BaseRule
{
    public function __construct(?string $message = null)
    {
        parent::__construct($message);
    }

    public function passes(): bool
    {
        return is_string($this->value) && mb_strtoupper($this->value) === $this->value;
    }

    public function message(): string
    {
        return "The {$this->field} field must be uppercase.";
    }
}
#[Uppercase]
public string $code;

#[Uppercase(message: 'Shout it!')]
public string $shout;

BaseRule implements the Mewtonium\Vanguard\Contracts\Rule contract (passes() + message()); a non-null message passed to the rule takes priority over the default returned by message().

Here's another example — a rule that uses a regular expression to reject values with leading or trailing whitespace:

use Mewtonium\Vanguard\Rules\BaseRule;

#[\Attribute(\Attribute::TARGET_PROPERTY)]
final class Trimmed extends BaseRule
{
    public function __construct(?string $message = null)
    {
        parent::__construct($message);
    }

    public function passes(): bool
    {
        return is_string($this->value) && preg_match('/^\s|\s$/', $this->value) === 0;
    }

    public function message(): string
    {
        return "The {$this->field} field must not have leading or trailing whitespace.";
    }
}

Preparing values before validation

A rule may implement the Mewtonium\Vanguard\Contracts\PreparesValue contract to transform a value before passes() runs. Vanguard calls prepare(mixed $value): mixed and validates the returned value, so $this->value inside passes() is the prepared value. This is how the built-in date rules cast Y-m-d strings to DateTimeInterface.

A date-based rule can reuse the Mewtonium\Vanguard\Concerns\PreparesDate trait, which implements prepare() for you. The property's own value is prepared automatically; prepare any date arguments you accept in the constructor, then compare them in passes():

use Mewtonium\Vanguard\Concerns\PreparesDate;
use Mewtonium\Vanguard\Contracts\PreparesValue;
use Mewtonium\Vanguard\Rules\BaseRule;

#[\Attribute(\Attribute::TARGET_PROPERTY)]
final class FutureDate extends BaseRule implements PreparesValue
{
    use PreparesDate;

    public function __construct(
        protected string|\DateTimeInterface $after,
        ?string $message = null,
    ) {
        $this->after = $this->prepare($after);

        parent::__construct($message);
    }

    public function passes(): bool
    {
        return $this->value instanceof \DateTimeInterface
            && $this->value > $this->after;
    }

    public function message(): string
    {
        return sprintf(
            'The %s field must be a date after %s.',
            $this->field,
            $this->format($this->after),
        );
    }
}
#[FutureDate('2025-01-01')]
public string $startsAt;

Strict vs. lenient date parsing

By default the PreparesDate trait is strict: a string that isn't a valid date throws a \DateException. Set $lenient = true when your rule should accept plain, non-date strings and date strings. An unrecognised string is then left untouched instead of throwing an exception.

Which one you want depends on what the rule does. For example:

  • Equal is lenient. It checks equality, which is just as valid for a plain string ('active') as for a date ('2025-01-01'), so non-date strings have to be allowed through.
  • GreaterThan, LessThan, Between (and the like) are strict. "Greater than" only makes sense for numbers and dates, so a non-date string is treated as a mistake and rejected.

If your rule needs lenient mode, set it in the constructor before preparing any values:

public function __construct(/* ... */)
{
    $this->lenient = true;

    // ...
}

Custom Validation Message

All validation rules support a custom error message. You can specify a custom message by passing the message argument:

#[Required(message: 'Please enter your first name.')]
#[MinLength(2, message: 'Your last name must be at least 2 characters long.')]

Handling Validation Errors

When validation fails, errors are stored in an ErrorBag instance:

if ($form->invalid()) {
    $errors = $form->errors(); // Returns an instance of `ErrorBag`

    // ...
}

Available methods:

$errors->all();         // Returns all validation errors
$errors->get($field);   // Returns all errors for a specific field
$errors->first($field); // Returns the first error for a specific field
$errors->has($field);   // Checks if a field has any errors
$errors->count();       // Total number of validation errors
$errors->flush();       // Clears the bag

Example Output

For the example in the "Usage" section, calling $errors->all() would return:

[
    'lastName' => [
        'Required' => 'Please provide your last name.',
        'MinLength' => 'The lastName field must be a minimum of 2 characters long.',
    ],
    'age' => [
        'Between' => 'The age field must be between 18 and 99.',
    ],
    'email' => [
        'Email' => 'The email field must be a valid email.',
    ],
    'country' => [
        'In' => 'The country field does not have a valid selection.',
        'Uppercase' => 'The country field must be uppercase.',
    ],
    'date' => [
        'GreaterOrEqual' => 'The date field must be greater than or equal to 2025-01-01.',
    ],
]

Changelog

See the full changelog here.

License

This project is open-source and available under the MIT license.

mewtonium/vanguard 适用场景与选型建议

mewtonium/vanguard 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 2 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 04 月 19 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 mewtonium/vanguard 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 mewtonium/vanguard 我们能提供哪些服务?
定制开发 / 二次开发

基于 mewtonium/vanguard 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 2
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 25
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-04-19