PHPackages                             jeckleee/tools - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Validation &amp; Sanitization](/categories/validation)
4. /
5. jeckleee/tools

ActiveLibrary[Validation &amp; Sanitization](/categories/validation)

jeckleee/tools
==============

Webman plugin jeckleee/tools

v1.2.13(5mo ago)121141MITPHPPHP &gt;=8.0

Since Jan 9Pushed 4w ago2 watchersCompare

[ Source](https://github.com/jeckleee/Tools)[ Packagist](https://packagist.org/packages/jeckleee/tools)[ RSS](/packages/jeckleee-tools/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (10)DependenciesVersions (15)Used By (0)

Jeckleee/Tools
==============

[](#jeckleeetools)

一个 PHP 数据验证和工具库，提供符合直觉的链式调用验证器，让数据验证变得简单高效。

主要特性
----

[](#主要特性)

- **数据验证** : 提供符合直觉的验证器，使用链式调用添加规则，方便记忆和使用
- **常用工具函数** : 封装了一些常用的数据处理方法
- **支持多种验证方式** : 批量验证、单字段验证、变量验证
- **灵活的配置** : 支持自定义异常、错误码、错误返回模式
- **丰富的验证规则** : 覆盖大部分常用验证场景
- **框架兼容** : 可在 Laravel、Webman、ThinkPHP 等主流 PHP 框架中直接使用

安装
--

[](#安装)

```
composer require jeckleee/tools
```

配置
--

[](#配置)

```
// 配置文件: config/plugin/jeckleee/tools/app.php
return [
    'enable' => true,
    // 定义验证失败以后抛出的异常, webman 框架建议使用 BusinessException::class
    'exception' => Exception::class,
    // 定义验证失败的错误码
    'exception_code' => 500,
    // 验证失败错误如何返回(immediate,collective)
    // immediate: 立即返回, 只要验证出现错误, 立即抛出当前错误字段的异常信息, 不再验证剩余的字段
    // collective: 集中返回, 验证全部字段, 收集所有异常, 验证结束后在异常 $e->getMessage() 中返回错误字段的列表, json 字符串形式
    'error_return_mode' => 'immediate', // 只支持 immediate 和 collective，其他值会抛异常
];
```

验证规则总览
------

[](#验证规则总览)

验证规则说明参数示例**基础验证**`required`字段必填，可设置一个默认值`required('默认值')``ifExisted`字段存在时才验证，否则跳过`ifExisted()``requiredWith`当指定字段存在且不为空时，当前字段必填`requiredWith('email')``requiredWithout`当指定字段不存在或为空时，当前字段必填`requiredWithout('phone')``same`当前字段值必须与指定字段值相同`same('password')``different`当前字段值必须与指定字段值不同`different('old_password')`**字符串验证**`strTrim`去除字段两端的空格、制表符、换行符等`strTrim()``strLength`字段的值必须在指定范围的长度`strLength(3, 32)``strStartWith`字段的值必须以指定的字符串开始`strStartWith('http')``strEndWith`字段的值必须以指定的字符串结尾`strEndWith('.com')``strAlpha`字段的值只能由字母组成`strAlpha()``strAlphaNum`字段的值只能由字母和数字组成，`true` 时必须同时包含字母和数字`strAlphaNum(true)``strLowercase`将字段的值转换为小写`strLowercase()``strUppercase`将字段的值转换为大写`strUppercase()`**数字验证**`betweenNumber`字段的值必须在某两个数字区间(含)`betweenNumber(1, 100)``cmpNumber`对字段进行比较，允许的符号: &gt;, &lt;, &gt;=, &lt;=, !=, =`cmpNumber('>', 18)``isNumber`字段的值必须是数字(int 或 float，字符串数字也通过)`isNumber()``isInt`字段的值必须是整数（int 类型或整数字符串，如 "123" 也通过）`isInt()``isFloat`字段的值必须是小数，可限制小数位数`isFloat(2)`**数组验证**`inArray`字段的值必须在数组中`inArray([1,2,3])``notInArray`字段的值必须不在数组中`notInArray(['admin'])``isArray`字段的值必须是数组`isArray()`**常用格式验证**`isEmail`字段的值必须是邮箱`isEmail()``isMobile`字段的值必须是中国大陆手机号`isMobile()``isDateFormat`字段的值必须是指定格式的时间字符串`isDateFormat('Y-m-d')``isIdCard`字段的值必须是中国大陆身份证号`isIdCard()``isUrl`字段的值必须是网址`isUrl()``isIp`字段的值必须是 IP 地址(ipv4 或 ipv6)`isIp('ipv4')``isBool`字段的值必须是布尔值`isBool()``isJson`字段的值必须是一个 json 字符串，`true` 时转为数组`isJson(true)``isBase64`字段的值必须是有效的Base64编码字符串`isBase64()`**文件验证**`isFile`文件校验，支持多种格式：
1. 原始 `$_FILES` 数组
2. Laravel 的 `Illuminate\Http\UploadedFile` 对象
3. Webman 的 `support\UploadFile` 对象
4. ThinkPHP 的 `think\file\UploadedFile` 对象
常见用法：
- `isFile($_FILES, ['jpg','png'], 1024)`
- `isFile($request->file(), ['pdf'], 2048)`
校验通过无返回值，失败则抛出异常`isFile($_FILES, ['jpg','png'], 1024)`**其他验证**`withRegex`使用正则表达式验证字段`withRegex('/^[a-z]+$/')``fun`使用自定义验证函数`fun(function($val){ return $val > 0; })`---

规则行为详解与注意事项
-----------

[](#规则行为详解与注意事项)

- **required($def = null)**
    - 字段必填。若传递 `$def`，当字段不存在时会自动赋值为 `$def` 并通过校验。
- **ifExisted()**
    - 字段存在时才验证，否则跳过。适合可选字段。
- **isInt()**
    - 接受 int 类型或整数字符串（如 "123"、"-456" 也通过）。
- **isNumber()**
    - 接受 int、float 及字符串数字（如 "123"、"12.3"）。
- **isFloat($decimalPlaces = null)**
    - 校验为浮点数，若指定 `$decimalPlaces`，则小数位数不能超过该值。
- **isFile($file, $ext = \[\], $maxSize\_Kb = 500)**
    - 支持多种文件对象，校验通过无返回值，失败则抛出异常。
    - `$file` 可为 `$_FILES`、Laravel/Webman/ThinkPHP 上传对象。
    - `$ext` 限制扩展名，空数组不限制。
    - `$maxSize_Kb` 最大文件大小，单位 KB，默认 500KB。
- **isJson(true)**
    - 校验为 json 字符串，`true` 时自动转为数组。
- **strAlphaNum(true)**
    - 必须同时包含字母和数字。
- **requiredWith/requiredWithout**
    - 依赖字段存在/不存在时，当前字段必填。
- **fun(callable)**
    - 传入自定义函数，返回 true 通过，否则抛出异常。

---

用法示例
----

[](#用法示例)

### 1. 批量验证表单数据

[](#1-批量验证表单数据)

```
use Jeckleee\Tools\Validator as V;

$post = [
    'name' => 'jeckleee',
    'password' => '123456',
    'password_confirm' => '123456',
    'email' => 'jeckleee@qq.com',
    'age' => 18,
    'avatar' => $_FILES['avatar'] ?? null
];

// 验证一组数据
$data = V::array($post, [
    // 基础验证
    V::field('name')->required()->strTrim()->strLength(3, 32)->verify('请填写正确的用户名'),
    // 密码验证
    V::field('password')->required()->strLength(6, 20)->verify('密码长度6-20位'),
    V::field('password_confirm')->same('password')->verify('两次密码不一致'),
    // 邮箱验证
    V::field('email')->required()->isEmail()->verify('请填写正确的邮箱'),
    // 年龄验证（只接受 int 类型）
    V::field('age')->required()->isInt()->betweenNumber(1, 120)->verify('请填写正确的年龄'),
    // 文件验证（第一个参数为 $_FILES，第二个为扩展名数组，第三个为最大 KB 数）
    V::field('avatar')->isFile($_FILES, ['jpg', 'png', 'gif'], 2*1024)->verify('头像格式或大小不正确'),
    // 条件验证
    V::field('phone')->requiredWithout('email')->isMobile()->verify('手机号或邮箱至少填写一个'),
    V::field('email_code')->requiredWith('email')->strLength(4, 6)->verify('邮箱验证码必填'),
    // 可选字段验证
    V::field('score')->ifExisted()->isInt()->betweenNumber(0, 100)->verify('请填写正确的分数'),
]);
// $data 包含所有验证通过的字段
```

### 2. 验证单个字段

[](#2-验证单个字段)

```
// 验证一个字段
$age = V::one($post, [
    V::field('age')->required()->isInt()->betweenNumber(1, 120)->verify('请填写正确的年龄'),
]);
echo $age; // 输出: 18
```

### 3. 验证变量

[](#3-验证变量)

```
// 验证变量是否正确, 返回 (bool) TRUE or FALSE
$phone = '123456789';
if (V::var($phone)->isMobile()->check()) {
    echo '手机号码正确';
} else {
    echo '手机号码不正确';
}
```

### 4. 自定义验证规则

[](#4-自定义验证规则)

```
// 自定义验证方法, 只有回调方法返回 (bool) true 时, 才验证通过
$data = V::one($post, [
    V::field('age')->fun(function ($value) {
        return $value >= 18;
    })->verify('年龄不能小于18岁'),
]);
```

### 5. 条件必填验证

[](#5-条件必填验证)

```
$data = V::array($input, [
    // 当邮箱存在时，验证码必填
    V::field('email')->required()->isEmail()->verify('邮箱格式错误'),
    V::field('email_code')->requiredWith('email')->strLength(4, 6)->verify('邮箱验证码必填'),
    // 当邮箱不存在时，手机号必填
    V::field('phone')->requiredWithout('email')->isMobile()->verify('手机号或邮箱至少填写一个'),
]);
```

### 6. 字段值比较验证

[](#6-字段值比较验证)

```
$data = V::array($input, [
    // 密码确认
    V::field('password')->required()->strLength(6, 20)->verify('密码长度6-20位'),
    V::field('password_confirm')->same('password')->verify('两次密码不一致'),
    // 新旧密码不能相同
    V::field('new_password')->required()->different('old_password')->verify('新密码不能与原密码相同'),
]);
```

### 7. 文件上传验证

[](#7-文件上传验证)

```
// 兼容多种文件上传格式
$data = V::array($request->all(), [
    // 原始 $_FILES 格式
    V::field('avatar')->isFile($_FILES, ['jpg', 'png', 'gif'], 2*1024)->verify('头像格式或大小不正确'),
    // Laravel 框架
    V::field('document')->isFile($request->file(), ['pdf', 'doc', 'docx'], 10*1024)->verify('文档格式或大小不正确'),
    // Webman 框架
    V::field('image')->isFile($request->file(), ['jpg', 'png'], 1024)->verify('图片格式或大小不正确'),
]);

// Laravel 使用示例
public function upload(Request $request)
{
    $data = V::array($request->all(), [
        V::field('avatar')->isFile($request->file(), ['jpg', 'png'], 2*1024)->verify('头像格式或大小不正确'),
        V::field('document')->isFile($request->file(), ['pdf'], 5*1024)->verify('文档格式或大小不正确'),
    ]);
    // ....处理文件上传
}

// Webman 使用示例
public function upload(Request $request)
{
    V::array($request->all(), [
        V::field('avatar')->isFile($request->file(), ['jpg', 'png'], 2*1024)->verify('头像格式或大小不正确'),
        V::field('document')->isFile($request->file(), ['pdf'], 5*1024)->verify('文档格式或大小不正确'),
    ]);
    // ...自己处理文件上传

}
```

### 8. JSON 字符串校验

[](#8-json-字符串校验)

```
// 校验并转为数组
$data = V::array($post, [
  V::field('data')->isJson(true)->verify('数据格式错误');
]);
```

### 9. Base64 编码校验

[](#9-base64-编码校验)

```
// 校验Base64编码字符串
$data = V::array($post, [
  V::field('image_data')->isBase64()->verify('图片数据格式错误');
]);
```

### 10. 浮点数校验

[](#10-浮点数校验)

```
// 校验并限制 2 位小数
$data = V::array($post, [
  V::field('price')->isFloat(2)->verify('价格格式错误');
]);
```

### 11. 数字比较

[](#11-数字比较)

```
$data = V::array($post, [
  V::field('age')->cmpNumber('>', 18)->verify('年龄必须大于18岁');
]);
```

### 12. isInt/isNumber/isFloat 区别示例

[](#12-isintisnumberisfloat-区别示例)

```
$data = V::array($post, [
  V::field('a')->isInt()->verify(); // 接受 int 或整数字符串（如 "123"）
  V::field('b')->isNumber()->verify(); // 接受 int/float/字符串数字
  V::field('c')->isFloat(2)->verify(); // 浮点数且最多2位小数
]);
```

### 13. isFile 返回值说明

[](#13-isfile-返回值说明)

```
// isFile对文件校验时,没有返回值
V::array($post, [
  // 校验通过无返回，失败则抛出异常
  V::field('avatar')->isFile($_FILES, ['jpg'], 1024)->verify();
]);
// ...自己处理文件上传
$avatar=$request->file('avatar')->store('uploads/avatar/avatar');
```

### 14. 自定义函数校验

[](#14-自定义函数校验)

```
$data = V::array($post, [
  V::field('score')->fun(function($val){ return $val > 60; })->verify('分数必须大于60');
]);
```

### 15. 字符串大小写转换

[](#15-字符串大小写转换)

```
$data = V::array($post, [
  // 转小写
  V::field('username')->strLowercase()->verify('用户名转小写失败');
  // 转大写
  V::field('code')->strUppercase()->verify('验证码转大写失败');
]);
```

---

异常处理
----

[](#异常处理)

### 自定义异常和错误码

[](#自定义异常和错误码)

```
// 1. 使用配置文件中定义异常和错误码
$data = V::array($post, [
    V::field('name')->required()->verify('请填写账号'),
]);

// 2. 在使用 array() 或者 one() 方法时定义异常和错误码
$data = V::array($post, [
    V::field('name')->required()->verify('请填写账号'),
], MyException::class, 500);

// 3. 在规则中的 ->verify() 方法中定义的错误码优先级最高
$data = V::array($post, [
    V::field('name')->required()->verify('请填写账号', 12001),
    V::field('age')->required()->isInt()->betweenNumber(1, 120)->verify('请填写正确的年龄', 12002),
]);
```

### 错误返回模式

[](#错误返回模式)

```
// immediate 模式：立即返回第一个错误
$data = V::array($post, $rules, null, null, 'immediate');

// collective 模式：收集所有错误后返回
$data = V::array($post, $rules, null, null, 'collective');
```

> `error_return_mode` 只支持 `immediate` 和 `collective`，否则会抛出异常。

---

完整使用示例
------

[](#完整使用示例)

```
use Jeckleee\Tools\Validator as V;
use support\Request;

class UserController extends BaseController
{
    public function register(Request $request): \support\Response
    {
        try {
            $input = V::array($request->all(), [
                // 基础信息验证
                V::field('username')->required()->strTrim()->strLength(3, 20)->strAlphaNum()->verify('用户名格式错误'),
                V::field('email')->required()->isEmail()->verify('邮箱格式错误'),
                V::field('phone')->requiredWithout('email')->isMobile()->verify('手机号或邮箱至少填写一个'),
                // 密码验证
                V::field('password')->required()->strLength(6, 20)->verify('密码长度6-20位'),
                V::field('password_confirm')->same('password')->verify('两次密码不一致'),
                // 个人信息验证
                V::field('age')->ifExisted()->isInt()->betweenNumber(1, 120)->verify('年龄格式错误'),
                V::field('avatar')->ifExisted()->isFile($request->file(), ['jpg', 'png'], 1024)->verify('头像格式或大小错误'),
                // 自定义验证
                V::field('invite_code')->fun(function($val) {
                    return strlen($val) === 6 && ctype_alnum($val);
                })->verify('邀请码格式错误'),
            ]);
            //需要自己处理处理头像的上传...todo
            $avatar = $request->file('avatar')->store('uploads/avatar/avatar');

            //将头像地址增加到$input数据中
            $input['avatar']=$avatar;
            // 创建用户
            $user = User::create($input);
            return json(['code' => 200, 'msg' => '注册成功', 'data' => $user]);
        } catch (BusinessException $exception) {
            return json([
                'code' => $exception->getCode() ?: 300,
                'msg' => $exception->getMessage(),
                'status' => 'error'
            ]);
        }
    }
}
```

---

工具函数
----

[](#工具函数)

除了验证器，本工具还提供了一些常用的工具函数：

```
use Jeckleee\Tools\Tool;

// 二维数组根据字段绑定到唯一键
$users = Tool::arrayBindKey($userList, 'id');
// $users = [1=>['id'=>1,'name'=>'A'], 2=>['id'=>2,'name'=>'B']]

// 二维数组根据字段排序
$sortedUsers = Tool::arraySequence($userList, 'age', 'SORT_DESC');
// $sortedUsers = [['id'=>2,'age'=>30], ['id'=>1,'age'=>20]]

// 生成树形结构
$tree = Tool::generateTree($list, 'id', 'parent_id', 'children');

// 生成随机字符串
$randomStr = Tool::getRandomString(16);

// 计算日期差
$days = Tool::diffDateDays('2024-01-01', '2024-01-10');

// 字符串脱敏
$masked = Tool::maskSecret('13812345678', 3, 4);

// 生成 UUID
$uuid = Tool::generateUUID();

// 安全 UUID v4 / 时间有序 UUID v7
$uuid4 = Tool::uuidV4();
$uuid7 = Tool::uuidV7();

// 安全随机数
$ri = Tool::randomInt(1, 100);
$rf = Tool::randomFloat(0.1, 9.9);

// 人性化时间差与字节显示
$diff = Tool::humanizeDiff('2025-01-01 12:00:00'); // 如："3天前"
$size = Tool::humanBytes(1234567); // 1.18 MB

// 稳定排序构建查询串（RFC3986）
$query = Tool::buildQuery(['b'=>2, 'a'=>['y'=>2, 'x'=>1]]); // a%5Bx%5D=1&a%5By%5D=2&b=2

// 分组、去重、分块、二分
$groups = Tool::arrayGroupBy([
  ['id'=>1,'cat'=>'A'],
  ['id'=>2,'cat'=>'B'],
  ['id'=>3,'cat'=>'A'],
], 'cat');
// [ 'A' => [...], 'B' => [...] ]

$uniq = Tool::arrayUniqueBy([
  ['id'=>1,'name'=>'x'],
  ['id'=>1,'name'=>'x2'],
  ['id'=>2,'name'=>'y'],
], 'id'); // 稳定去重，保留首次出现

$chunks = Tool::arrayChunkFixed([1,2,3,4,5], 2); // [[1,2],[3,4],[5]]

[$evens, $odds] = Tool::arrayPartition([1,2,3,4], fn($n)=> $n%2===0);

// 树相关：扁平化、查找、路径
$flat = Tool::flattenTree($tree, 'children');
$found = Tool::findInTree($tree, fn($node)=> ($node['id']??null) === 5);
$pathInTree = Tool::pathInTree($tree, 5, 'id', 'children'); // 从根到目标的路径数组

// 从扁平数组追溯路径
$flatNodes = [
  ['id'=>1,'parent_id'=>null],
  ['id'=>2,'parent_id'=>1],
  ['id'=>5,'parent_id'=>2],
];
$path = Tool::pathInFlat($flatNodes, 5, 'id', 'parent_id');

// 重试工具
$result = Tool::retry(function(int $attempt){
  if ($attempt < 3) throw new Exception('try again');
  return 'ok';
}, times: 5, sleepMs: 100);
```

### 工具函数说明

[](#工具函数说明)

- **Tool::arrayBindKey($arr, $key)**
    - 作用：二维数组按某字段转为以该字段为 key 的关联数组。
    - 示例： ```
        $arr = [['id'=>1,'name'=>'A'], ['id'=>2,'name'=>'B']];
        $res = Tool::arrayBindKey($arr, 'id');
        // [1=>['id'=>1,'name'=>'A'], 2=>['id'=>2,'name'=>'B']]
        ```
- **Tool::arraySequence($arr, $field, $sort = 'SORT\_DESC')**
    - 作用：按指定字段排序，支持 SORT\_ASC/SORT\_DESC。
    - 示例： ```
        $arr = [['id'=>1,'age'=>20], ['id'=>2,'age'=>18]];
        $res = Tool::arraySequence($arr, 'age', 'SORT_ASC');
        // [['id'=>2,'age'=>18], ['id'=>1,'age'=>20]]
        ```
- **Tool::arrayGroupBy($arr, string|callable $key)**
    - 作用：按键名或回调分组，返回键为字符串的分组映射。
- **Tool::arrayUniqueBy($arr, string|callable $key)**
    - 作用：按键稳定去重，保留首次出现的元素。
- **Tool::arrayChunkFixed($arr, int $size)**
    - 作用：按固定长度分块，size&lt;=0 时返回原数组。
- **Tool::arrayPartition($arr, callable $predicate)**
    - 作用：按谓词拆分为 \[匹配数组, 不匹配数组\]。
- **Tool::generateTree($list, $idField='id', $parentField='p\_id', $children='children')**
    - 作用：生成树形结构（基于父子引用）。
- **Tool::flattenTree($tree, $children='children')**
    - 作用：扁平化树，移除子节点字段。
- **Tool::findInTree($tree, callable $predicate, $children='children')**
    - 作用：在树中查找首个满足条件的节点。
- **Tool::pathInTree($tree, mixed $id, $idField='id', $children='children')**
    - 作用：返回从根到目标节点的路径数组，未找到返回空数组。
- **Tool::pathInFlat($flat, mixed $id, $idField='id', $parentField='parent\_id')**
    - 作用：在扁平数组中自底向上追溯父级路径。
- **Tool::getRandomString(int $length)**
    - 作用：生成长度为 length 的随机字符串（URL 安全字符集）。
- **Tool::maskSecret(string $str, int $startKeep, int $endKeep, string $mask='\*', ?int $maxLen=null)**
    - 作用：字符串脱敏，支持多字节字符与最大长度限制。
- **Tool::humanizeDiff(DateTime|string $datetime)**
    - 作用：人性化时间差：刚刚/秒前/分钟前/小时前/天前/日期时间。
- **Tool::humanBytes(int|float $bytes, int $precision=2)**
    - 作用：人类可读的字节单位展示（B/KB/MB/GB/TB/PB）。
- **Tool::buildQuery(array $params)**
    - 作用：递归键排序后，按 RFC3986 规则构建查询字符串，稳定可复现。
- **Tool::generateUUID()**
    - 作用：基于 mt\_rand 的不安全 UUID（非加密安全）。
- **Tool::uuidV4()**
    - 作用：安全 UUID v4（random\_bytes），RFC 4122 兼容。
- **Tool::uuidV7()**
    - 作用：时间有序的 UUID v7，便于索引与排序。
- **Tool::randomInt(int $min, int $max)**
    - 作用：生成加密安全的随机整数（含边界）。
- **Tool::randomFloat(float $min, float $max)**
    - 作用：生成 \[min, max\] 区间随机浮点数。
- **Tool::diffDateDays(string $date1, string $date2)**
    - 作用：计算两个日期间相差天数。
- **Tool::retry(callable $fn, int $times=3, int $sleepMs=100, ?callable $shouldRetry=null)**
    - 作用：失败自动重试；可自定义重试判定与重试间隔。

---

注意事项
----

[](#注意事项)

1. **验证规则顺序**：建议将 `required` 规则放在最前面，避免对空值进行不必要的验证。
2. **错误消息**：可以为每个规则自定义错误消息，提高用户体验。
3. **性能考虑**：使用 `ifExisted` 规则可以避免对不存在字段的验证。
4. **文件验证**：文件验证支持多种格式：
    - 原始 `$_FILES` 数组格式
    - Laravel 的 `Illuminate\Http\UploadedFile` 对象
    - Webman 的 `support\UploadFile` 对象
    - ThinkPHP 的 `think\file\UploadedFile` 对象
5. **条件验证**：合理使用 `requiredWith` 和 `requiredWithout` 可以处理复杂的表单逻辑。
6. **isInt/isNumber 区别**：`isInt` 接受 int 类型 和 字符串整数 ；`isNumber` 可接受字符串数字 和 浮点数字符串。
7. **isFloat**：可限制小数位数。
8. **isJson**：`true` 时自动转为数组。
9. **框架兼容性**：可在 Laravel、Webman、ThinkPHP 等框架中使用。
10. **配置函数依赖**：如需自定义配置，需保证 `config()` 函数可用。

---

贡献
--

[](#贡献)

欢迎提交 Issue 和 Pull Request 来完善这个工具！

许可证
---

[](#许可证)

MIT License

###  Health Score

43

—

FairBetter than 90% of packages

Maintenance85

Actively maintained with recent releases

Popularity18

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~29 days

Recently: every ~49 days

Total

14

Last Release

153d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/3ff70e0567c11e50e09ccb2a30b455d2568cfa287cfc192c93fd6d67e106d80b?d=identicon)[jeckleee](/maintainers/jeckleee)

---

Top Contributors

[![jeckleee](https://avatars.githubusercontent.com/u/27334331?v=4)](https://github.com/jeckleee "jeckleee (118 commits)")

---

Tags

laravelvalidatorwebman

### Embed Badge

![Health badge](/badges/jeckleee-tools/health.svg)

```
[![Health](https://phpackages.com/badges/jeckleee-tools/health.svg)](https://phpackages.com/packages/jeckleee-tools)
```

###  Alternatives

[illuminatech/validation-composite

Allows uniting several validation rules into a single one for easy re-usage

180517.4k](/packages/illuminatech-validation-composite)[laravel-validation-rules/phone

Validate that a phone number is in the correct format

69365.2k](/packages/laravel-validation-rules-phone)[stuyam/laravel-phone-validator

A phone validator for Laravel using the free Twilio phone lookup service.

2861.7k](/packages/stuyam-laravel-phone-validator)[laravel-validation-rules/us-state

Validate US States and Canada Provinces

16177.7k](/packages/laravel-validation-rules-us-state)[laravel-validation-rules/timezone

Validate that a given timezone is valid.

2119.0k](/packages/laravel-validation-rules-timezone)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
