henzeb/ruler-laravel 问题修复 & 功能扩展

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

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

henzeb/ruler-laravel

Composer 安装命令:

composer require henzeb/ruler-laravel

包简介

extends Laravel's validator using their own Rule interface

README 文档

README

Build Status Latest Version on Packagist Total Downloads Test Coverage

This library enhances the way you work with Laravel's validation Rules. It allows you to use your Rule classes as string-based validators and group rules into reusable rulesets.

For example: Laravel has bundled a rule for enums. As the parameter you pass is a string, you should be able to use it like this:

 [
   'attribute'=>'required|enum:App\Enums\YourEnum'
 ]

right?

wrong!

In order to use it like this, you need to extend your Validator and use the Illuminate\Validation\Rules\Enum rule, or create your own version. This library simplifies that process.

I've gone ahead and registered enum for you, but you can just as easily add your own rules.

Installation

You can install the package via composer:

composer require henzeb/ruler-laravel

note: I only support PHP ^8.1 because of the enums.

Usage

Simply add the Henzeb\Ruler\Concerns\Ruler trait to your service provider and add your rules to the $rules property.

use Henzeb\Ruler\Concerns\Ruler;
use Illuminate\Support\ServiceProvider;
use App\Rules\YourRule;
use App\Rules\YourOtherRule;

class YourProvider extends ServiceProvider
{
    use Ruler;
    
    private array $rules = [
        'your_rule' => YourRule::class,
        YourOtherRule::class
    ]; 
}

You can either specify a name, or just let Ruler create a name for you.

For example: YourOtherRule will get the name your_other_rule.

If your provider needs to implement the boot method, just call the bootRuler method inside that boot method

use Henzeb\Ruler\Concerns\Ruler;
use Illuminate\Support\ServiceProvider;
use App\Rules\YourRule;
use App\Rules\YourOtherRule;

class YourProvider extends ServiceProvider
{
    use Ruler;
    
    private array $rules = [
        'your_rule' => YourRule::class,
        YourOtherRule::class
    ]; 
    
    public function boot() {
        $this->bootRuler();
        // your code
    }
}

It is also possible to do it yourself in case you need to do it conditionally.

use Henzeb\Ruler\Concerns\Ruler;
use Illuminate\Support\ServiceProvider;
use App\Rules\YourRule;
use App\Rules\YourOtherRule;

class YourProvider extends ServiceProvider
{
    use Ruler;

    public function boot() {
        if(/** some condition */) {
            $this->rule(YourRule::class, 'your_rule');
        }

        if(/** some condition */) {
            $this->rule(YourOtherRule::class);
        }
        // your code
    }
}

Registering rules via the Rule facade

You can also register rules directly using the Rule facade, without needing a service provider:

use Illuminate\Validation\Rule;
use App\Rules\YourRule;
use App\Rules\YourOtherRule;

Rule::register(YourRule::class, 'your_rule');
Rule::register(YourOtherRule::class);

You can also pass an array to register multiple rules at once:

Rule::register([
    'your_rule' => YourRule::class,
    YourOtherRule::class,
]);

The Rule class

The rules are implemented just like any other Rule you'd normally define. So you'll be familiar with the implementation.

use Illuminate\Contracts\Validation\Rule;

class YourRule implements Rule {

    public function passes($attribute, $value)
    {
        // your validation code
    }
    
    public function message() 
    {
        return 'Message when fails';
    }
}

Note: You can also use invokable rules here.

Parameters

You can use parameters. Just add a constructor with the parameters in the order you'd like to use them. Optional parameters are supported.

Note: As for now, you'll receive them as strings, no casting to other scalars is done at this time.

public function __construct(private string $param1, private string $param2 = null){}

Implicit rules

To add an implicit rule, all you have to do is implement the Illuminate\Contracts\Validation\ImplicitRule interface. Ruler will do the rest for you.

use Illuminate\Contracts\Validation\ImplicitRule;

class YourImplicitRule implements ImplicitRule {
    // the code
}

Dependent rules

To add a dependent rule, just implement the Illuminate\Contracts\Validation\DataAwareRule interface. interface Ruler will do the rest for you.

use Illuminate\Contracts\Validation\DataAwareRule;

class DependentRule implements DataAwareRule {
    private array $data;
    
    public function setData(array $data) {
        $this->data = $data;
        return $this;
    }
    
    // your code 
}
Validator aware rules

Ruler also supports Validator aware rules. Just implement the required interface.

mixing up interfaces

You can mix up the interfaces just like you would in vanilla Laravel. For instance: A rule that is implicit can also be dependent

The error message

The error message should be placed in the message method as defined in Illuminate\Contracts\Validation\Rule, just as you normally would.

The message method is called dynamically, which means you can store the message in your Rule instance and return it in the message method.

use Henzeb\Ruler\Contracts\ReplacerAwareRule;
use Illuminate\Contracts\Validation\Rule;

class YourRule implements Rule
{
    return string $message = 'Something went wrong';
    
    public __construct($param_1, $paramTwo) {}
    
    public function passes($attribute, $value)
    {
        $this->message = 'Your error message';
        return false;
    }
    
    public function message()
    {
        return return $this->message;
    }
}

It also supports returning arrays. When an array is returned, the MessageBag contains the messages as if they were coming from different validation rules. This way your Rule can do grouped validations (for instance using another Validator instance).

replacers

Out of the box, you can use :<number> to point to a parameter, but if you want them named, you can use the Henzeb\Ruler\Contracts\ReplacerAwareRule interface.

use Henzeb\Ruler\Contracts\ReplacerAwareRule;

class YourRule implements ReplacerAwareRule
{
    public __construct($param_1, $paramTwo) {}
    
    public function message()
    {
        return ':attribute :param_1 :paramTwo';
    }

    public function replacers(): array
    {
        return [
            'param_1',
            'paramTwo'
        ];
    }
}

The parameters are in order as specified. param_1 will point to the value of $param_1 and so on.

Closures

You can add a Closure to a replacer if you have specific needs. A Closure always receives the value of the current parameter, the attributes name, the other parameters (named) and all the fields that are under validation.

class YourRule implements ReplacerAwareRule
{
    public function message()
    {
        return ':attribute :param_1 :paramTwo';
    }

    public function replacers(): array
    {
        return [
            'param_1'=> function(string $value, string $attribute, array $parameters, array $data) {
                return 'any string'.$parameters['paramTwo']
            },
            'paramTwo'
        ];
    }
}

Ruleset

The Ruleset class allows you to group multiple validation rules into a single reusable rule object. Instead of writing a custom Rule with manual validation logic, you define a set of existing Laravel rules that are applied together.

Basic usage

Extend the Henzeb\Ruler\Ruleset class and implement the rules method:

use Henzeb\Ruler\Ruleset;

class NameRuleset extends Ruleset
{
    protected function rules(): array
    {
        return ['required', 'string', 'min:3'];
    }
}

Then use it like any other rule object:

Validator::make($data, [
    'name' => [new NameRuleset()],
]);

You can also return rules as a string:

protected function rules(): string
{
    return 'required|string|min:3';
}

Implicit behavior

By default, a Ruleset is implicit, meaning it validates even when the value is empty. You can disable this by setting the $implicit property to false:

$ruleset = new NameRuleset();
$ruleset->implicit = false;

Custom messages and attributes

Override the messages and attributes methods to customize error messages and attribute names:

use Henzeb\Ruler\Ruleset;

class NameRuleset extends Ruleset
{
    protected function rules(): array
    {
        return ['required', 'string', 'min:3'];
    }

    protected function messages(): array
    {
        return ['min' => 'Too short!'];
    }

    protected function attributes(): array
    {
        return ['name' => 'username'];
    }
}

Configuring the inner validator

The configure method gives you access to the underlying Validator instance, allowing you to use features like stopOnFirstFailure or sometimes:

use Henzeb\Ruler\Ruleset;
use Illuminate\Validation\Validator;

class NameRuleset extends Ruleset
{
    protected function rules(): array
    {
        return ['required', 'string', 'min:3'];
    }

    protected function configure(Validator $validator): void
    {
        $validator->stopOnFirstFailure();
    }
}

Using with the Ruler trait

A Ruleset can also be registered as a string-based rule via the Ruler trait, just like any other rule:

private array $rules = [
    'name_ruleset' => NameRuleset::class,
];

This allows you to use it as a string:

Validator::make($data, [
    'name' => 'name_ruleset',
]);

Overriding the Validator resolver

Because Ruler has a custom Validator instance set to resolve by Laravel, you need to extend the Henzeb\Ruler\Validator\RulerValidator class in case you want to change the resolver.

Testing

composer test

Changelog

Please see CHANGELOG for more information what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email henzeberkheij@gmail.com instead of using the issue tracker.

Credits

License

The GNU AGPLv. Please see License File for more information.

henzeb/ruler-laravel 适用场景与选型建议

henzeb/ruler-laravel 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 198 次下载、GitHub Stars 达 1, 最近一次更新时间为 2022 年 02 月 13 日, 在 PHP 生态内属于活跃度较高的组件。

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

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

围绕 henzeb/ruler-laravel 我们能提供哪些服务?
定制开发 / 二次开发

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

BUG 修复 & 性能优化

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

项目外包 & 长期维护

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

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

统计信息

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

GitHub 信息

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

其他信息

  • 授权协议: AGPL-3.0-only
  • 更新时间: 2022-02-13