承接 aegisora/guardian 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

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

aegisora/guardian

Composer 安装命令:

composer require aegisora/guardian

包简介

Lightweight validation rule execution orchestrator for the Aegisora ecosystem

README 文档

README

Code Coverage Badge Software License PHPStan Badge

Aegisora Guardian is a lightweight and extensible validation orchestrator for the Aegisora ecosystem.

The package provides a fluent and predictable way to execute validation rules against arbitrary values using the standardized architecture defined in aegisora/rule-contract.

Guardian focuses on:

  • centralized validation execution
  • structured validation results
  • custom exception handling
  • sequential rule pipelines
  • clean and framework-agnostic architecture

The library is intentionally minimalistic while still being powerful enough to build complex domain validation layers.

✨ Features

Fluent Validation Pipeline

Guardian allows validation rules to be chained together in a readable and expressive way.

$guardian
    ->that($value)
    ->must(FirstRule::create())
    ->must(SecondRule::create())
    ->validate();

This makes complex validation scenarios easy to maintain and extend.

Rule-Based Validation

Validation logic is completely separated into independent rule objects implementing:

Aegisora\RuleContract\RuleInterface

This promotes:

  • single responsibility
  • reusable validation logic
  • domain-oriented architecture
  • testability

Structured Validation Flow

Guardian follows a strict validation flow:

Value → Context → Rule → Result → Exception

Each rule receives a Context object and returns a standardized Result object.

No raw booleans are used internally.

Custom Exception Handling

Every rule can define its own exception.

This enables precise domain-level error handling:

->must(
    EmailRule::create(),
    new InvalidEmailException()
)

Lightweight Architecture

The package has:

  • no framework dependencies
  • minimal memory overhead
  • simple object graph
  • predictable behavior

Guardian can be used in:

  • Laravel
  • Symfony
  • Slim
  • custom PHP applications
  • microservices
  • domain-driven projects

Safe Rule Execution

Internal rule execution is protected from unexpected contract-level failures.

If a rule throws RuleException, Guardian converts it into:

GuardianExecutingRuleException

This keeps the validation layer consistent and isolated.

📦 Installation

Install the package via Composer:

composer require aegisora/guardian

🔗 Related Packages

Guardian is part of the broader Aegisora ecosystem.

Several ready-to-use validation rules are already implemented as separate packages and can be found in the official Aegisora repositories:

https://github.com/orgs/Aegisora/repositories

Rule repositories follow a consistent naming convention:

*-rule

Examples:

These packages provide reusable validation logic fully compatible with Guardian and aegisora/rule-contract.

The ecosystem is designed to allow combining independent validation rules into flexible and composable validation pipelines.

📚 Requirements

Required Package

Guardian relies on:

aegisora/rule-contract

which provides:

  • RuleInterface
  • Context
  • Result
  • RuleException

🚀 Core Concept

Guardian acts as a validation execution engine.

Instead of manually invoking validation logic throughout the application, Guardian centralizes the process and provides a consistent execution model.

Validation flow:

  1. A value is passed into Guardian
  2. Validation rules are attached
  3. Guardian creates a Context
  4. Rules are executed sequentially
  5. Every rule returns a Result
  6. Validation failures trigger exceptions

This architecture makes validation:

  • predictable
  • composable
  • extensible
  • easy to debug
  • easy to test

🏗️ Basic Usage

Simple Validation

The simplest way to validate a value is using check().

use Aegisora\Guardian\Guardian;

$guardian = new Guardian();

$guardian->check(
    $value,
    FooRule::create()
);

If validation passes, execution continues normally.

If validation fails, Guardian throws:

GuardianValidationException

Validation with Custom Exception

You may provide a custom exception for validation failures.

use Aegisora\Guardian\Guardian;
use App\Exceptions\InvalidValueException;

$guardian = new Guardian();

$guardian->check(
    $value,
    FooRule::create(),
    new InvalidValueException()
);

If validation fails, the provided exception will be thrown instead of the default Guardian exception.

This is especially useful in:

  • domain-driven design
  • business validation layers
  • API validation
  • application services

🔗 Fluent Validation API

Guardian supports fluent rule chaining through GuardianExecutor.

Example:

use Aegisora\Guardian\Guardian;

$guardian = new Guardian();

$guardian
    ->that($value)
    ->must(FirstRule::create())
    ->must(SecondRule::create())
    ->validate();

Execution behavior:

  • rules execute sequentially
  • validation stops on first failure
  • exceptions are thrown immediately
  • successful rules continue pipeline execution

Multiple Rules with Different Exceptions

Each rule may define its own exception.

$guardian
    ->that($value)
    ->must(
        EmailRule::create(),
        new InvalidEmailException()
    )
    ->must(
        PasswordRule::create(),
        new WeakPasswordException()
    )
    ->validate();

This enables extremely precise validation semantics.

🧩 Real-World Example: User Registration Validation

Guardian can be used in an application service to validate incoming data before executing business logic.

In this example, a user registration command is validated by three independent rules:

  • email must have a valid format
  • password must be strong enough
  • user must be at least 18 years old

Guardian does not contain validation logic itself. It receives a value, passes it into rules through Context, executes rules one by one, and stops on the first failed rule.

Registration Command

The command contains the data required to register a user.

<?php

namespace App\Registration;

final class RegisterUserCommand
{
    private string $email;
    private string $password;
    private int $age;

    public function __construct(
        string $email,
        string $password,
        int $age
    ) {
        $this->email = $email;
        $this->password = $password;
        $this->age = $age;
    }

    public function getEmail(): string
    {
        return $this->email;
    }

    public function getPassword(): string
    {
        return $this->password;
    }

    public function getAge(): int
    {
        return $this->age;
    }
}

Email Rule

This rule checks that the command contains a valid email address.

<?php

namespace App\Registration\Rules;

use Aegisora\RuleContract\Models\Context;
use Aegisora\RuleContract\Models\Result;
use Aegisora\RuleContract\Rule;
use App\Registration\RegisterUserCommand;

final class ValidEmailRule extends Rule
{
    protected function executeValidate(Context $context): Result
    {
        $command = $context->getValue();

        if (!$command instanceof RegisterUserCommand) {
            return Result::invalid('invalid_registration_command');
        }

        if (filter_var($command->getEmail(), FILTER_VALIDATE_EMAIL) === false) {
            return Result::invalid('invalid_email');
        }

        return Result::valid();
    }
}

Password Rule

This rule checks that the password is at least 12 characters long and contains both an uppercase letter and a number.

<?php

namespace App\Registration\Rules;

use Aegisora\RuleContract\Models\Context;
use Aegisora\RuleContract\Models\Result;
use Aegisora\RuleContract\Rule;
use App\Registration\RegisterUserCommand;

final class StrongPasswordRule extends Rule
{
    protected function executeValidate(Context $context): Result
    {
        $command = $context->getValue();

        if (!$command instanceof RegisterUserCommand) {
            return Result::invalid('invalid_registration_command');
        }

        $password = $command->getPassword();

        if (strlen($password) < 12) {
            return Result::invalid('weak_password');
        }

        if (preg_match('/[A-Z]/', $password) !== 1) {
            return Result::invalid('weak_password');
        }

        if (preg_match('/[0-9]/', $password) !== 1) {
            return Result::invalid('weak_password');
        }

        return Result::valid();
    }
}

Age Rule

This rule checks that the user is old enough to register.

<?php

namespace App\Registration\Rules;

use Aegisora\RuleContract\Models\Context;
use Aegisora\RuleContract\Models\Result;
use Aegisora\RuleContract\Rule;
use App\Registration\RegisterUserCommand;

final class AdultUserRule extends Rule
{
    private const MINIMUM_AGE = 18;

    protected function executeValidate(Context $context): Result
    {
        $command = $context->getValue();

        if (!$command instanceof RegisterUserCommand) {
            return Result::invalid('invalid_registration_command');
        }

        if ($command->getAge() < self::MINIMUM_AGE) {
            return Result::invalid('user_is_too_young');
        }

        return Result::valid();
    }
}

Application Service

The service describes the validation pipeline. Each rule may have its own domain exception.

<?php

namespace App\Registration;

use Aegisora\Guardian\Guardian;
use App\Registration\Exceptions\InvalidEmailException;
use App\Registration\Exceptions\UserIsTooYoungException;
use App\Registration\Exceptions\WeakPasswordException;
use App\Registration\Rules\AdultUserRule;
use App\Registration\Rules\StrongPasswordRule;
use App\Registration\Rules\ValidEmailRule;

final class RegisterUserService
{
    private Guardian $guardian;
    private UserRepository $users;

    public function __construct(
        Guardian $guardian,
        UserRepository $users
    ) {
        $this->guardian = $guardian;
        $this->users = $users;
    }

    public function register(RegisterUserCommand $command): User
    {
        $this->guardian
            ->that($command)
            ->must(
                new ValidEmailRule(),
                new InvalidEmailException()
            )
            ->must(
                new StrongPasswordRule(),
                new WeakPasswordException()
            )
            ->must(
                new AdultUserRule(),
                new UserIsTooYoungException()
            )
            ->validate();

        return $this->users->create(
            $command->getEmail(),
            password_hash($command->getPassword(), PASSWORD_DEFAULT),
            $command->getAge()
        );
    }
}

Usage

<?php

use Aegisora\Guardian\Exceptions\GuardianExecutingRuleException;
use App\Registration\Exceptions\InvalidEmailException;
use App\Registration\Exceptions\UserIsTooYoungException;
use App\Registration\Exceptions\WeakPasswordException;
use App\Registration\RegisterUserCommand;

try {
    $user = $registerUserService->register(
        new RegisterUserCommand(
            'john@example.com',
            'SecurePassword123',
            25
        )
    );

    return [
        'status' => 201,
        'user_id' => $user->getId(),
    ];
} catch (InvalidEmailException $exception) {
    return [
        'status' => 422,
        'error' => 'Invalid email address.',
    ];
} catch (WeakPasswordException $exception) {
    return [
        'status' => 422,
        'error' => 'Password is too weak.',
    ];
} catch (UserIsTooYoungException $exception) {
    return [
        'status' => 422,
        'error' => 'User must be at least 18 years old.',
    ];
} catch (GuardianExecutingRuleException $exception) {
    return [
        'status' => 500,
        'error' => 'Validation rule execution failed.',
    ];
}

If all rules pass, the user is created.

If one rule fails, Guardian immediately stops execution and throws the exception attached to that rule.

For example, if ValidEmailRule fails, InvalidEmailException is thrown. StrongPasswordRule and AdultUserRule will not be executed.

If a rule fails internally and throws RuleException, Guardian converts it into GuardianExecutingRuleException, keeping rule execution errors separate from business validation errors.

🏛️ Architecture

Guardian contains several small and focused components.

Guardian

Main entry point for validation operations.

Responsibilities:

  • starts validation process
  • creates validation pipeline
  • provides simple API
  • delegates execution to GuardianExecutor

Methods:

check($value, RuleInterface $rule, Throwable $exception = null): void
that($value): GuardianExecutor

GuardianExecutor

Core validation execution engine.

Responsibilities:

  • stores validation rules
  • creates validation context
  • executes rules sequentially
  • analyzes validation results
  • throws exceptions

Methods:

must(RuleInterface $rule, Throwable $exception = null): self
validate(): void

GuardRule

Immutable transport object containing:

  • validation rule
  • optional exception

Purpose:

  • encapsulates validation configuration
  • keeps executor implementation clean

GuardValue

Simple wrapper around arbitrary validated value.

Purpose:

  • encapsulates raw input value
  • centralizes value transport

⚙️ Validation Lifecycle

Complete internal validation lifecycle:

Guardian::check()
        ↓
GuardianExecutor
        ↓
Context::create($value)
        ↓
Rule::validate(Context)
        ↓
Result
        ↓
Validation Analysis
        ↓
Exception or Success

🚨 Exceptions

Guardian defines dedicated exceptions for predictable error handling.

GuardianValidationException

Thrown when validation fails and no custom exception is provided.

Example:

throw new GuardianValidationException(
    $failedRuleCode
);

The exception contains the failed rule code returned by Result.

GuardianExecutingRuleException

Thrown when internal rule execution fails due to contract-level exceptions.

Example scenario:

RuleException → GuardianExecutingRuleException

This protects application code from low-level rule implementation failures.

🧠 Validation Philosophy

Guardian follows several important principles.

Explicit Validation

Validation should be visible and explicit.

Bad:

if (!$value) {
}

Good:

$guardian->check($value, SomeRule::create());

Domain-Oriented Exceptions

Validation errors should communicate domain meaning.

Example:

new InvalidUserEmailException()

instead of generic runtime errors.

Structured Result Objects

Rules should return standardized objects instead of booleans.

This enables:

  • extensibility
  • debugging
  • metadata support
  • consistent validation behavior

Separation of Concerns

Guardian separates:

  • validation execution
  • validation rules
  • result analysis
  • exception handling

This keeps code maintainable and scalable.

⚖️ License

This package is open-source and licensed under the MIT License. See the LICENSE for details.

🌱 Contributing

Contributions are welcome and greatly appreciated!. See the CONTRIBUTING for details.

🌟 Support

If you find this project useful, please consider giving it a star on GitHub!

It helps the project grow and motivates further development of the Aegisora ecosystem.

aegisora/guardian 适用场景与选型建议

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

它主要适用于以下技术方向: 「php」 「validator」 「validation」 「rules」 「guard」 「guardian」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

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

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

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

BUG 修复 & 性能优化

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

项目外包 & 长期维护

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

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

统计信息

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

GitHub 信息

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

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-06-11