rakit/validation

类似Laravel的独立验证库

v1.4.0 2020-08-27 05:07 UTC

README

Build Status Coverage Status License

PHP独立数据验证库。受Laravel的Illuminate\Validation启发。

功能

  • 类似Laravel验证的API。
  • 数组验证。
  • $_FILES验证,支持多文件。
  • 自定义属性别名。
  • 自定义验证消息。
  • 自定义规则。

要求

  • PHP 7.0或更高版本
  • Composer用于安装

快速入门

安装

composer require "rakit/validation"

使用

使用此库验证数据有两种方式。使用make创建验证对象,然后使用validate进行验证。或者直接使用validate。示例

使用make

<?php

require('vendor/autoload.php');

use Rakit\Validation\Validator;

$validator = new Validator;

// make it
$validation = $validator->make($_POST + $_FILES, [
    'name'                  => 'required',
    'email'                 => 'required|email',
    'password'              => 'required|min:6',
    'confirm_password'      => 'required|same:password',
    'avatar'                => 'required|uploaded_file:0,500K,png,jpeg',
    'skills'                => 'array',
    'skills.*.id'           => 'required|numeric',
    'skills.*.percentage'   => 'required|numeric'
]);

// then validate
$validation->validate();

if ($validation->fails()) {
    // handling errors
    $errors = $validation->errors();
    echo "<pre>";
    print_r($errors->firstOfAll());
    echo "</pre>";
    exit;
} else {
    // validation passes
    echo "Success!";
}

或直接validate

<?php

require('vendor/autoload.php');

use Rakit\Validation\Validator;

$validator = new Validator;

$validation = $validator->validate($_POST + $_FILES, [
    'name'                  => 'required',
    'email'                 => 'required|email',
    'password'              => 'required|min:6',
    'confirm_password'      => 'required|same:password',
    'avatar'                => 'required|uploaded_file:0,500K,png,jpeg',
    'skills'                => 'array',
    'skills.*.id'           => 'required|numeric',
    'skills.*.percentage'   => 'required|numeric'
]);

if ($validation->fails()) {
	// handling errors
	$errors = $validation->errors();
	echo "<pre>";
	print_r($errors->firstOfAll());
	echo "</pre>";
	exit;
} else {
	// validation passes
	echo "Success!";
}

在这种情况下,上述两个示例将输出相同的结果。

但使用make可以在验证运行之前设置一些自定义无效消息、自定义属性别名等。

属性别名

默认情况下,我们将您的属性转换为更易读的文本。例如,confirm_password将显示为Confirm password。但您可以使用setAliassetAliases方法将其设置为任何您想要的。

示例

$validator = new Validator;

// To set attribute alias, you should use `make` instead `validate`.
$validation->make([
	'province_id' => $_POST['province_id'],
	'district_id' => $_POST['district_id']
], [
	'province_id' => 'required|numeric',
	'district_id' => 'required|numeric'
]);

// now you can set aliases using this way:
$validation->setAlias('province_id', 'Province');
$validation->setAlias('district_id', 'District');

// or this way:
$validation->setAliases([
	'province_id' => 'Province',
	'district_id' => 'District'
]);

// then validate it
$validation->validate();

现在如果province_id的值为空,错误消息将是'Province is required'。

自定义验证消息

在注册/设置自定义消息之前,这里有一些您可以在自定义消息中使用的变量

  • :attribute:将被替换为属性别名。
  • :value:将被替换为属性的字面值。对于数组和对象,将替换为JSON。

还有根据其规则的一些消息变量。

以下是一些注册/设置自定义消息的方法

为验证器设置自定义消息

使用这种方法,每次您使用makevalidate进行验证时,都会为它设置自定义消息。这对于本地化很有用。

为此,您可以将自定义消息作为构造函数的第一个参数设置,如下所示

$validator = new Validator([
	'required' => ':attribute harus diisi',
	'email' => ':email tidak valid',
	// etc
]);

// then validation belows will use those custom messages
$validation_a = $validator->validate($dataset_a, $rules_for_a);
$validation_b = $validator->validate($dataset_b, $rules_for_b);

或使用setMessages方法,如下所示

$validator = new Validator;
$validator->setMessages([
	'required' => ':attribute harus diisi',
	'email' => ':email tidak valid',
	// etc
]);

// now validation belows will use those custom messages
$validation_a = $validator->validate($dataset_a, $rules_for_dataset_a);
$validation_b = $validator->validate($dataset_b, $rules_for_dataset_b);

为验证设置自定义消息

有时您可能想为特定的验证设置自定义消息。为此,您可以将自定义消息作为$validator->make$validator->validate的第三个参数设置,如下所示

$validator = new Validator;

$validation_a = $validator->validate($dataset_a, $rules_for_dataset_a, [
	'required' => ':attribute harus diisi',
	'email' => ':email tidak valid',
	// etc
]);

或者您可以使用$validation->setMessages,如下所示

$validator = new Validator;

$validation_a = $validator->make($dataset_a, $rules_for_dataset_a);
$validation_a->setMessages([
	'required' => ':attribute harus diisi',
	'email' => ':email tidak valid',
	// etc
]);

...

$validation_a->validate();

为特定属性规则设置自定义消息

有时您可能想为特定规则属性设置自定义消息。为此,您可以使用:作为消息分隔符或使用链式方法。

示例

$validator = new Validator;

$validation_a = $validator->make($dataset_a, [
	'age' => 'required|min:18'
]);

$validation_a->setMessages([
	'age:min' => '18+ only',
]);

$validation_a->validate();

或使用链式方法

$validator = new Validator;

$validation_a = $validator->make($dataset_a, [
	'photo' => [
		'required',
		$validator('uploaded_file')->fileTypes('jpeg|png')->message('Photo must be jpeg/png image')
	]
]);

$validation_a->validate();

翻译

翻译与自定义消息不同。翻译可能在您使用自定义消息用于规则innot_inmimesuploaded_file时需要。

例如,如果您使用规则in:1,2,3,我们将设置无效消息为"The Attribute only allows '1', '2', or '3'",其中"1", "2", 或 "3"部分来自":allowed_values"标签。所以如果您有自定义的印尼语消息":attribute hanya memperbolehkan :allowed_values",我们将设置无效消息为"Attribute hanya memperbolehkan '1', '2', or '3'",其中"or"这个词不是印尼语的一部分。

因此,为了解决这个问题,我们可以使用翻译,如下所示

// Set translation for words 'and' and 'or'.
$validator->setTranslations([
    'and' => 'dan',
    'or' => 'atau'
]);

// Set custom message for 'in' rule
$validator->setMessage('in', ":attribute hanya memperbolehkan :allowed_values");

// Validate
$validation = $validator->validate($inputs, [
    'nomor' => 'in:1,2,3'
]);

$message = $validation->errors()->first('nomor'); // "Nomor hanya memperbolehkan '1', '2', atau '3'"

实际上,我们内置的规则只使用单词"and"和"or",您可能需要将其翻译。

与错误消息一起工作

错误信息被收集在 Rakit\Validation\ErrorBag 对象中,您可以使用 errors() 方法获取它。

$validation = $validator->validate($inputs, $rules);

$errors = $validation->errors(); // << ErrorBag

现在您可以使用以下方法检索错误信息

all(string $format = ':message')

获取所有消息作为扁平数组。

示例

$messages = $errors->all();
// [
//     'Email is not valid email',
//     'Password minimum 6 character',
//     'Password must contains capital letters'
// ]

$messages = $errors->all('<li>:message</li>');
// [
//     '<li>Email is not valid email</li>',
//     '<li>Password minimum 6 character</li>',
//     '<li>Password must contains capital letters</li>'
// ]

firstOfAll(string $format = ':message', bool $dotNotation = false)

只获取所有现有键中的第一个消息。

示例

$messages = $errors->firstOfAll();
// [
//     'email' => Email is not valid email',
//     'password' => 'Password minimum 6 character',
// ]

$messages = $errors->firstOfAll('<li>:message</li>');
// [
//     'email' => '<li>Email is not valid email</li>',
//     'password' => '<li>Password minimum 6 character</li>',
// ]

参数 $dotNotation 用于数组验证。如果它是 false,则返回原始数组结构;如果它是 true,则返回带有点符号键的扁平数组。

例如

$messages = $errors->firstOfAll(':message', false);
// [
//     'contacts' => [
//          1 => [
//              'email' => 'Email is not valid email',
//              'phone' => 'Phone is not valid phone number'
//          ],
//     ],
// ]

$messages = $errors->firstOfAll(':message', true);
// [
//     'contacts.1.email' => 'Email is not valid email',
//     'contacts.1.phone' => 'Email is not valid phone number',
// ]

first(string $key)

获取给定键的第一个消息。如果有错误消息,则返回 string,如果没有错误,则返回 null

例如

if ($emailError = $errors->first('email')) {
    echo $emailError;
}

toArray()

按键分组获取所有消息。

例如

$messages = $errors->toArray();
// [
//     'email' => [
//         'Email is not valid email'
//     ],
//     'password' => [
//         'Password minimum 6 character',
//         'Password must contains capital letters'
//     ]
// ]

count()

获取消息数量。

has(string $key)

检查给定的键是否有错误。如果键有错误,则返回 bool,否则返回。

获取验证、有效和无效数据

例如,您有如下验证

$validation = $validator->validate([
    'title' => 'Lorem Ipsum',
    'body' => 'Lorem ipsum dolor sit amet ...',
    'published' => null,
    'something' => '-invalid-'
], [
    'title' => 'required',
    'body' => 'required',
    'published' => 'default:1|required|in:0,1',
    'something' => 'required|numeric'
]);

您可以使用以下示例中的方法获取验证数据、有效数据或无效数据

$validatedData = $validation->getValidatedData();
// [
//     'title' => 'Lorem Ipsum',
//     'body' => 'Lorem ipsum dolor sit amet ...',
//     'published' => '1' // notice this
//     'something' => '-invalid-'
// ]

$validData = $validation->getValidData();
// [
//     'title' => 'Lorem Ipsum',
//     'body' => 'Lorem ipsum dolor sit amet ...',
//     'published' => '1'
// ]

$invalidData = $validation->getInvalidData();
// [
//     'something' => '-invalid-'
// ]

可用规则

点击显示详细信息。

required

此验证字段下的字段必须存在且不为 '空'。

以下是一些示例

对于上传的文件,$_FILES['key']['error'] 必须不是 UPLOAD_ERR_NO_FILE

required_if:another_field,value_1,value_2,...

此规则下的字段必须存在且不为空,如果 anotherfield 字段等于任何值。

例如,required_if:something,1,yes,on 如果 something 的值是 1'1''yes''on' 之一,则必须验证。

required_unless:another_field,value_1,value_2,...

除非 anotherfield 字段等于任何值,否则验证字段必须存在且不为空。

required_with:field_1,field_2,...

验证字段必须存在且不为空,只有当其他指定的字段中有一个存在时。

required_without:field_1,field_2,...

验证字段必须存在且不为空,只有当其他指定的字段中没有一个存在时。

required_with_all:field_1,field_2,...

验证字段必须存在且不为空,只有当其他所有指定的字段都存在时。

required_without_all:field_1,field_2,...

验证字段必须存在且不为空,只有当其他所有指定的字段都不存在时。

uploaded_file:min_size,max_size,extension_a,extension_b,...

此规则将验证来自 $_FILES 的数据。此规则下的字段必须遵循以下规则才能有效

  • $_FILES['key']['error'] 必须是 UPLOAD_ERR_OKUPLOAD_ERR_NO_FILE。对于 UPLOAD_ERR_NO_FILE,您可以使用 required 规则进行验证。
  • 如果指定了最小大小,上传文件的大小 不得 小于最小大小。
  • 如果指定了最大大小,上传文件的大小 不得 大于最大大小。
  • 如果指定了文件类型,MIME 类型必须是给定类型之一。

以下是一些示例定义和说明

  • uploaded_file:上传的文件是可选的。如果它不为空,则必须是 ERR_UPLOAD_OK
  • required|uploaded_file:上传的文件是必需的,并且必须是 ERR_UPLOAD_OK
  • uploaded_file:0,1M:上传文件的大小必须在 0 - 1 MB 之间,但上传文件是可选的。
  • required|uploaded_file:0,1M,png,jpeg:上传文件的大小必须在 0 - 1MB 之间,并且 MIME 类型必须是 image/jpegimage/png

可选地,如果您想在不同大小的验证和类型验证之间有单独的错误消息,您可以使用 mimes 规则来验证文件类型,并使用 minmaxbetween 来验证它的大小。

对于多个文件上传,PHP会给出一个不理想的$_FILES数组结构(有关详细信息,请参阅此处)。因此,我们创建了uploaded_file规则来自动解析您的$_FILES值,使其成为一个组织良好的数组结构。这意味着,您不仅可以使用minmaxbetweenmimes规则来验证多个文件上传,还应该使用uploaded_file来解析其值并确保该值是正确的已上传文件值。

例如,如果您有如下输入文件:

<input type="file" name="photos[]"/>
<input type="file" name="photos[]"/>
<input type="file" name="photos[]"/>

您可以直接这样验证:

$validation = $validator->validate($_FILES, [
    'photos.*' => 'uploaded_file:0,2M,jpeg,png'
]);

// or

$validation = $validator->validate($_FILES, [
    'photos.*' => 'uploaded_file|max:2M|mimes:jpeg,png'
]);

或者,如果您有如下输入文件:

<input type="file" name="images[profile]"/>
<input type="file" name="images[cover]"/>

您可以这样验证:

$validation = $validator->validate($_FILES, [
    'images.*' => 'uploaded_file|max:2M|mimes:jpeg,png',
]);

// or

$validation = $validator->validate($_FILES, [
    'images.profile' => 'uploaded_file|max:2M|mimes:jpeg,png',
    'images.cover' => 'uploaded_file|max:5M|mimes:jpeg,png',
]);

现在,当您使用getValidData()getInvalidData()时,您将得到一个与单文件上传相同的良好数组结构。

mimes:extension_a,extension_b,...

在验证过程中,$_FILES下的项必须具有与列出的扩展名之一对应的MIME类型。

default/defaults

这是一个特殊的规则,它不会验证任何内容。如果属性为空或不存在,它将为您的属性设置默认值。

例如,如果您有如下验证:

$validation = $validator->validate([
    'enabled' => null
], [
    'enabled' => 'default:1|required|in:0,1'
    'published' => 'default:0|required|in:0,1'
]);

$validation->passes(); // true

// Get the valid/default data
$valid_data = $validation->getValidData();

$enabled = $valid_data['enabled'];
$published = $valid_data['published'];

验证通过,因为我们为enabledpublished设置了默认值10,这是有效的。然后我们可以获取有效/默认数据。

email

在验证过程中,该字段必须是有效的电子邮件地址。

uppercase

在验证过程中,该字段必须是有效的全大写。

lowercase

在验证过程中,该字段必须是有效的全小写。

json

在验证过程中,该字段必须是有效的JSON字符串。

alpha

在此规则下,字段必须是全部字母字符。

numeric

在此规则下,字段必须是数字。

alpha_num

在此规则下,字段必须是全部字母数字字符。

alpha_dash

在此规则下,字段可以包含字母数字字符、破折号和下划线。

alpha_spaces

在此规则下,字段可以包含字母字符以及空格。

in:value_1,value_2,...

在此规则下,该字段必须包含在给定的值列表中。

此规则使用in_array来检查值。默认情况下,in_array禁用严格检查。因此,它不会检查数据类型。如果您想启用严格检查,可以像在in规则中示例那样调用验证器:

$validation = $validator->validate($data, [
    'enabled' => [
        'required',
        $validator('in', [true, 1])->strict()
    ]
]);

然后'enabled'值应该是布尔值true,或整数1

not_in:value_1,value_2,...

在此规则下,该字段不得包含在给定的值列表中。

此规则也使用in_array。您可以通过调用验证器并像上面示例中的in规则那样调用strict()来启用严格检查。

min:number

在此规则下,该字段的大小必须大于或等于给定的数字。

对于字符串值,大小对应于字符数。对于整数或浮点值,大小对应于其数值。对于数组,大小对应于数组的计数。如果您的值是数值字符串,您可以将numeric规则放在其中以按数值值处理其大小而不是字符数。

您还可以使用此规则验证上传的文件,以验证上传文件的最小大小。例如

$validation = $validator->validate([
    'photo' => $_FILES['photo']
], [
    'photo' => 'required|min:1M'
]);
max:number

在此规则下,该字段的大小必须小于或等于给定的数字。值大小计算方式与min规则相同。

您还可以使用此规则验证上传的文件,以验证上传文件的最大大小。例如

$validation = $validator->validate([
    'photo' => $_FILES['photo']
], [
    'photo' => 'required|max:2M'
]);
between:min,max

在此规则下,该字段的大小必须在min和max参数之间。值大小计算方式与minmax规则相同。

您还可以使用此规则验证上传的文件,以验证上传文件的大小。例如

$validation = $validator->validate([
    'photo' => $_FILES['photo']
], [
    'photo' => 'required|between:1M,2M'
]);
digits:值

正在验证的字段必须是数字,且长度必须精确为

digits_between:最小值,最大值

正在验证的字段长度必须在最小值最大值之间。

url

此规则下的字段必须是有效的URL格式。默认情况下,它会检查常见的URL方案格式,如任何方案://...。但你可以指定URL方案。

例如

$validation = $validator->validate($inputs, [
    'random_url' => 'url',          // value can be `any_scheme://...`
    'https_url' => 'url:http',      // value must be started with `https://`
    'http_url' => 'url:http,https', // value must be started with `http://` or `https://`
    'ftp_url' => 'url:ftp',         // value must be started with `ftp://`
    'custom_url' => 'url:custom',   // value must be started with `custom://`
    'mailto_url' => 'url:mailto',   // value must conatin valid mailto URL scheme like `mailto:a@mail.com,b@mail.com`
    'jdbc_url' => 'url:jdbc',       // value must contain valid jdbc URL scheme like `jdbc:mysql://localhost/dbname`
]);

对于常见的URL方案和mailto,我们结合FILTER_VALIDATE_URL来验证URL格式,并使用preg_match来验证其方案。除了JDBC URL之外,目前它仅检查有效的JDBC方案。

integer此规则下的字段必须是整数。
boolean

此规则下的字段必须是布尔值。接受的输入包括truefalse10"1""0"

ip

此规则下的字段必须是有效的IPv4或IPv6。

ipv4

此规则下的字段必须是有效的IPv4。

ipv6

此规则下的字段必须是有效的IPv6。

extension:扩展_a,扩展_b,...

此规则下的字段必须以列出的其中一个扩展结束。

这在验证给定路径或URL的文件类型时很有用。应使用mimes规则来验证上传。

array

此规则下的字段必须是数组。

same:另一个字段

此规则下的字段值必须与另一个字段的值相同。

regex:/你的正则表达式/

此规则下的字段必须与给定的正则表达式匹配。

date:格式

此规则下的字段必须是有效的日期格式。参数格式是可选的,默认格式为Y-m-d

accepted

此规则下的字段必须是以下之一:'on''yes''1''true'true

present

此规则下的字段必须存在,无论其值是什么。

different:另一个字段

same相反。此规则下的字段值必须与另一个字段的值不同。

after:明天

任何可以被strtotime解析的都可以作为此规则的参数。有效的示例包括

  • after:next week
  • after:2016-12-31
  • after:2016
  • after:2016-12-31 09:56:02
before:昨天

这也与after规则相同。传递任何可以被strtotime解析的内容

callback

你可以使用此规则来定义自己的验证规则。此规则不能使用字符串管道进行注册。要使用此规则,你应该将闭包放在规则数组中。

例如

$validation = $validator->validate($_POST, [
    'even_number' => [
        'required',
        function ($value) {
            // false = invalid
            return (is_numeric($value) AND $value % 2 === 0);
        }
    ]
]);

你可以通过返回一个字符串来设置无效信息。例如,上面的示例将是

$validation = $validator->validate($_POST, [
    'even_number' => [
        'required',
        function ($value) {
            if (!is_numeric($value)) {
                return ":attribute must be numeric.";
            }
            if ($value % 2 !== 0) {
                return ":attribute is not even number.";
            }
            // you can return true or don't return anything if value is valid
        }
    ]
]);

注意:Rakit\Validation\Rules\Callback实例已绑定到你的闭包。因此,你可以使用$this访问规则属性和方法。

nullable

此规则下的字段可能为空。

注册/覆盖规则

使用自定义验证规则的另一种方法是创建一个扩展Rakit\Validation\Rule的类。然后使用setValidatoraddValidator进行注册。

例如,你想创建一个unique验证器,该验证器从数据库中检查字段的可用性。

首先,让我们创建UniqueRule

<?php

use Rakit\Validation\Rule;

class UniqueRule extends Rule
{
    protected $message = ":attribute :value has been used";

    protected $fillableParams = ['table', 'column', 'except'];

    protected $pdo;

    public function __construct(PDO $pdo)
    {
        $this->pdo = $pdo;
    }

    public function check($value): bool
    {
        // make sure required parameters exists
        $this->requireParameters(['table', 'column']);

        // getting parameters
        $column = $this->parameter('column');
        $table = $this->parameter('table');
        $except = $this->parameter('except');

        if ($except AND $except == $value) {
            return true;
        }

        // do query
        $stmt = $this->pdo->prepare("select count(*) as count from `{$table}` where `{$column}` = :value");
        $stmt->bindParam(':value', $value);
        $stmt->execute();
        $data = $stmt->fetch(PDO::FETCH_ASSOC);

        // true for valid, false for invalid
        return intval($data['count']) === 0;
    }
}

然后你需要将UniqueRule实例注册到验证器中,如下所示

use Rakit\Validation\Validator;

$validator = new Validator;

$validator->addValidator('unique', new UniqueRule($pdo));

现在你可以这样使用它

$validation = $validator->validate($_POST, [
    'email' => 'email|unique:users,email,exception@mail.com'
]);

在上面的UniqueRule中,属性$message用于默认的无效信息。属性$fillable_params用于fillParameters方法(在Rakit\Validation\Rule类中定义)。默认情况下,fillParameters将填充$fillable_params中列出的参数。例如,上面的示例中的unique:users,email,exception@mail.com将设置

$params['table'] = 'users';
$params['column'] = 'email';
$params['except'] = 'exception@mail.com';

如果您想让自定义规则接受类似 innot_inuploaded_file 的参数列表,您只需要在自定义规则类中重写 fillParameters(array $params) 方法。

请注意,我们上面创建的 unique 规则也可以这样使用

$validation = $validator->validate($_POST, [
    'email' => [
    	'required', 'email',
    	$validator('unique', 'users', 'email')->message('Custom message')
    ]
]);

因此,您可以通过添加一些返回其自身实例的方法来改进上面的 UniqueRule

<?php

use Rakit\Validation\Rule;

class UniqueRule extends Rule
{
    ...

    public function table($table)
    {
        $this->params['table'] = $table;
        return $this;
    }

    public function column($column)
    {
        $this->params['column'] = $column;
        return $this;
    }

    public function except($value)
    {
        $this->params['except'] = $value;
        return $this;
    }

    ...
}

然后您可以以更酷的方式使用它,如下所示

$validation = $validator->validate($_POST, [
    'email' => [
    	'required', 'email',
    	$validator('unique')->table('users')->column('email')->except('exception@mail.com')->message('Custom message')
    ]
]);

隐式规则

隐式规则是一种规则,如果它无效,则忽略后续规则。例如,如果属性未通过 required* 规则,则大多数情况下,后续规则也将无效。因此,为了防止我们的后续规则消息被收集,我们将 required* 规则设置为隐式。

要使您的自定义规则为隐式,可以将 $implicit 属性的值设置为 true。例如

<?php

use Rakit\Validation\Rule;

class YourCustomRule extends Rule
{

    protected $implicit = true;

}

修改值

在某些情况下,您可能希望自定义规则能够修改其属性值,如我们的 default/defaults 规则。因此,在当前和后续规则检查中,将使用您修改的值。

为此,您应该实现 Rakit\Validation\Rules\Interfaces\ModifyValue 并在您的自定义规则类中创建 modifyValue($value) 方法。

例如

<?php

use Rakit\Validation\Rule;
use Rakit\Validation\Rules\Interfaces\ModifyValue;

class YourCustomRule extends Rule implements ModifyValue
{
    ...

    public function modifyValue($value)
    {
        // Do something with $value

        return $value;
    }

    ...
}

验证前钩子

您可能在验证运行之前想要做一些准备工作。例如,我们的 uploaded_file 规则将解析来自 $_FILES(不理想的)数组结构的属性值,将其转换为有组织的数组结构,这样我们就可以像验证其他数据一样验证多个文件上传。

为此,您应该实现 Rakit\Validation\Rules\Interfaces\BeforeValidate 并在您的自定义规则类中创建 beforeValidate() 方法。

例如

<?php

use Rakit\Validation\Rule;
use Rakit\Validation\Rules\Interfaces\BeforeValidate;

class YourCustomRule extends Rule implements BeforeValidate
{
    ...

    public function beforeValidate()
    {
        $attribute = $this->getAttribute(); // Rakit\Validation\Attribute instance
        $validation = $this->validation; // Rakit\Validation\Validation instance

        // Do something with $attribute and $validation
        // For example change attribute value
        $validation->setValue($attribute->getKey(), "your custom value");
    }

    ...
}