chippyash/validation

基于功能的全面验证程序

3.0.0 2020-01-04 07:54 UTC

This package is auto-updated.

Last update: 2024-09-04 17:59:39 UTC


README

质量保证

PHP 7.2 Build Status Test Coverage Code Climate

上述徽章代表当前的开发分支。一般情况下,除非测试、覆盖率和可用性可以接受,否则我不会向GitHub推送代码。在假期期间,需要为其他下游项目编写代码等情况下,这可能并不适用。如果您需要稳定的代码,请使用标记版本。阅读“进一步文档”和“安装”。

请注意,该库在2.0.0版本中取消了PHP5.4 & 5.5的开发者支持。如果您需要PHP 5.4或5.5的支持,请使用版本 >=1,<2

该库在3.0.0版本中取消了PHP <7.2的支持。如果您需要PHP 5.6 - 7.1的支持,请使用版本 ~2.0

是什么?

提供对嵌套结构的广泛且复杂的验证。主要用例是验证传入的Json数据,与XML不同,在常见用法中不存在定义的验证模式。(XML有XSD。)

为什么?

验证传入数据很重要,因为您不能信任数据提供者。程序中的早期警告使其变得健壮。在大型和/或企业系统中,您上游的数据提供者可能会在没有您知道的情况下更改。能够验证数据是否符合预期模式可以防止您的应用程序不必要地失败。

一个健壮的系统首先过滤,然后验证,然后可选地再次过滤(通常称为映射)任何传入的数据。该库提供了一个与Zend Validator兼容的扩展,允许您创建嵌套数据的复杂验证。

如何

如果您不知道为什么某些东西失败了,验证就不会相同。所有Chippyash Validators都使用Chippyash/Validation/Messenger类来存储验证错误,并记录验证通过的原因。有时,知道为什么它成功同样重要。

所有Chippyash Validators都支持在验证类上调用,在这种情况下,您需要提供消息传递者

    use Chippyash\Validation\Messenger;
    use Chippyash\Validation\Common\Double as Validator;
        
    $messenger = new Messenger();
    $validator = new Validator();
    $result = $validator($someValue, $messenger);
    $msg = $messenger->implode();
    if (!$result) {
        echo $msg;
    } else {
        //parse the messages and switch dependent on why it succeeded
    }
    

或者,您也可以调用isValid()方法,在这种情况下,您不需要提供消息传递者

    use Chippyash\Validation\Common\Double as Validator;
        
    $validator = new Validator();
    $result = $validator->isValid($someValue);
    if (!$result) {
        $errMsg = implode(' : ', $validator->getMessages());
    }

简单验证器

  • Chippyash\Validation\Common\DigitString: 值是否仅包含数字字符?
  • Chippyash\Validation\Common\Double: 传入的字符串是否等同于双精度浮点值(float);
  • Chippyash\Validation\Common\Email: 传入的字符串是否是一个简单的电子邮件地址
  • Chippyash\Validation\Common\Enum: 传入的字符串是否属于一组已知的字符串之一
    use Chippyash\Validation\Common\Enum;
      
    $validator = new Enum(['foo','bar']);
    $ret = $validator->isValid('bop'); //returns false
  • Chippyash\Validation\Common\IsArray: 传入的值是否是一个数组?
  • Chippyash\Validation\Common\ArrayKeyExists: 值是数组和具有所需键的数组吗?
  • Chippyash\Validation\Common\ArrayKeyNotExists: 值是数组和没有所需键的数组吗?
  • Chippyash\Validation\Common\IsTraversable: 传入的值是否可遍历?
  • Chippyash\Validation\Common\Netmask: 传入的IP地址是否属于构造的子网掩码(CIDR)
    use Chippyash\Validation\Common\Netmask;
    
    $validator = new Netmask('0.0.0.0/1');
    return $validator->isValid('127.0.0.1);  //return true
    return $validator->isValid('128.0.0.1);  //return false

您可以使用单个CIDR地址掩码或一组CIDR地址来构造Netmask Validator。如果用null IP调用isValid(或调用它),它将尝试从$_SERVER['REMOTE_ADDR']或$_SERVER['HTTP_X_FORWARDED_FOR']中获取IP,这使得它非常适合其主要用例,即保护您的Web应用程序免受未经授权的IP地址请求。

有关Netmask validator的更多用法,请参阅测试用例。

  • Chippyash\Validation\Common\UKPostCode: 对Zend PostCode的简单扩展,用于检查英国邮编。应容易创建您自己的特定国家的验证器;
  • Chippyash\Validation\Common\UKTelNum。又是对Zend TelNum Validator的简单扩展
  • Chippyash\Validation\Common\ZFValidator:一个简单的类,允许您扩展它以使用Zend验证器创建任何验证器。

复杂验证器

从这里开始,我们将偏离Zend验证器。

  • Chippyash\Validation\Common\ArrayPart. 值是否为数组,是否存在所需的键,以及它是否根据传入的函数参数进行验证?
    use Chippyash\Validation\Common\ArrayPart;
    use Chippyash\Validation\Common\Enum;
    
    $validator = new ArrayPart('idx', new Enum(['foo','bar'])); 
    $ret = $validator->isValid(['idx' => 'bop']); //false  
    $ret = $validator->isValid(['foo' => 'bop']); //false  
    $ret = $validator->isValid(['idx' => 'bar']); //true  
  • Chippyash\Validation\Common\Lambda。Lambda验证器在构造时期望一个函数,该函数接受一个值并返回true或false
    use Chippyash\Validation\Common\Lambda;
    
    $validator = new Lambda(function($value) {
        return $value === 'foo';
    });
    
    $ret = $validator->isValid('bar'); //false    

您可以将可选的第二StringType参数与失败消息一起传入

    use Chippyash\Validation\Common\Lambda;
    use Chippyash\Type\String\StringType;
        
    $validator = new Lambda(function($value) {
        return $value === 'foo';
    },
        new StringType('Oops, not a Foo');
    
    if (!$validator->isValid('bar')) { //false
        $errMsg = implode(' : ', $validator->getMessages());
    }

如果您想手动处理添加错误消息,可以在函数声明中将Messenger参数指定为第二个参数

    use Chippyash\Validation\Messenger;
    use Chippyash\Validation\Common\Lambda;
    
    $validator = new Lambda(function($value, Messenger $messenger) {
            if ($value != 'foo') {
                $messenger->add('error message');
                return false;
            }
            return true;
        }
    );
  • Chippyash\Validation\Common\ISO8601DateString:提供的字符串是否符合ISO8601日期字符串模式。 文档待定。这个验证器非常复杂,可能值得它自己的库。所以请小心,它可能从这个版本中被移除!

模式验证器

模式验证器允许您验证复杂的数据结构。这些数据结构通常是可以遍历的(数组、具有公共参数的对象、实现遍历接口的对象等)。它们是这个库的有用性的核心。

例如,假设我们有某些传入的Json

$json = '
{
    "a": "2015-12-01",
    "b": false,
    "c": [
        {
            "d": "fred",
            "e": "NN10 6HB"
        },
        {
            "d": "jim",
            "e": "EC1V 7DA"
        },
        {
            "d": "maggie",
            "e": "LE4 4HB"
        },
        {
            "d": "sue",
            "e": "SW17 9JR"
        }
    ],
    "f": [
        "a@b.com",
        "c@d.co.uk"
    ]
}
';

我们首先会将其转换为PHP可以理解的东西,即。

    $value = json_decode($json);  //or use the Zend\Json class for solid support

HasTypeMap

HasTypeMap验证器允许我们验证传入数据的键和值,因此构成了任何复杂验证要求的核心。

use Chippyash\Validation\Pattern\HasTypeMap;
use Chippyash\Validation\Common\ISO8601DateString;
use Chippyash\Validation\Common\IsArray;
use Chippyash\Validation\Common\Email;

$validator = new HasTypeMap([
    'a' => new ISO8601DateString(), 
    'b' => 'boolean', 
    'c' => new IsArray(), 
    'f' => new IsArray()
]);

$ret = $validator->isValid($value);

请注意,对于'c'和'f'元素,我们能做的最好的事情就是确定它是否为数组。请参见下面的'Repeater'以了解如何解决这个问题。

在TypeMap中提供的值可以是以下之一

  • PHP gettype()返回的任何值,即 "integer" "double" "string","boolean","resource","NULL","unknown"
  • 类的名称,例如 '\Chippyash\Type\String\StringType'
  • 符合签名 'function($value, Messenger $messenger)' 的函数并返回true或false
  • 实现ValidationPatternInterface的对象

Repeater

Repeater模式允许我们验证非关联数组值。其构造函数为

__construct(ValidatorPatternInterface $validator, IntType $min = null, IntType $max = null)

如果$min === null,则默认为1。如果$max === null,则默认为-1,即没有最大值。

现在我们可以重写我们的验证器来验证整个输入数据

use Chippyash\Validation\Pattern\HasTypeMap;
use Chippyash\Validation\Pattern\Repeater;
use Chippyash\Validation\Common\ISO8601DateString;
use Chippyash\Validation\Common\IsArray;
use Chippyash\Validation\Common\Email;
use Chippyash\Validation\Common\UKPostCode;

$validator = new HasTypeMap([
    'a' => new ISO8601DateString(),
    'b' => 'boolean',
    'c' => new Repeater(
        new HasTypeMap([
            'd' => 'string',
            'e' => new UKPostCode()
        ]),
        null,
        4
    ),
    'f' => new Repeater(new Email())
]);

$ret = $validator->isValid($value);

这表示'c'元素必须包含1-4个符合给定TypeMap的项目。您可以在examples/has-type-map.php脚本中看到它的实际操作。

逻辑验证器

这些验证器允许您执行布尔逻辑。LAnd、LOr、LNot和LXor按预期工作。

每个都需要ValidatorPatternInterface构造参数。以下是一个表面上的例子

    use Chippyash\Validation\Logical;
    use Chippyash\Validation\Common\Lambda;
    
    $true = new Lambda(function($value){return true;});
    $false = new Lambda(function($value){return false;});

    $and = new Logical\LAnd($true, $false);
    $or = new Logical\LOr($true, $false);
    $not = new Logical\LNot($true);
    $xor = new Logical\LXor($true, $false);

当然,您可以将它们组合起来

    $validator = new Logical\LNot( new Logical\LAnd($true, Logical\LXor($false, $true)))
    $ret = $validator->isValid('foo');
    
    //the above is equivelent to
    $ret = !( true && (false xor true)) 

这个功能的真正强大之处在于,它允许您创建替代验证

    $nullOrDate = new LOr(
        new Lambda(function($value) {
            return is_null($value);
        },
        new Lambda(function($value) {
            try {new \DateTime($value); return true;} catch (\Exception $e) { return false;}
        })
    );

验证处理器

所有上述内容都假设您正在对数据执行单个验证,并且所有由验证器模式指定的项目都存在于传入数据中。当您有可选项目时会发生什么?这就是验证处理器出现的地方。

ValidationProcessor允许您对数据进行多次验证。通常,您会首先对所需数据项进行验证,然后运行一个或多个后续验证以检查可选项目。

要使用,用您的第一个(通常是必需项)验证器构造处理器,然后简单地向其中添加额外的验证器。

$validator = new ValidationProcessor($requiredValidator);
$validator->add($optionalValidator);

运行您的验证,并收集所需的任何错误消息

if (!$validator->validate($value)) {
    var_dump($validator->getMessenger()->implode());
}

处理器将按顺序运行每个验证并返回组合结果。请参阅examples/validation-processor.php以获取更多说明。

更多信息

请注意,您在GitHub上看到的此文档始终是最新版本的dev-master。它描述的功能可能尚未发布。请检查您所使用的版本的文档,或下载。

测试合约在docs目录中。

查看ZF4软件包以获取更多软件包。

UML

更改库

  1. 创建分支
  2. 编写测试
  3. 修改
  4. 发起拉取请求

发现了一个你无法解决的bug吗?

  1. 创建分支
  2. 编写测试
  3. 发起拉取请求

注意。在发起拉取请求之前,确保你rebase到HEAD。

或者 - 提出一个问题票据。

在哪里?

库托管在Github上。它可在Packagist.org找到。

安装

安装Composer

用于生产

    "chippyash/validation": ">=3,<4"

或者使用最新版本,可能是不稳定的版本。

    "chippyash/validation": "dev-master"

用于开发

克隆此仓库,然后在本地仓库根目录中运行Composer以引入依赖项。

    git clone git@github.com:chippyash/Validation.git Validation
    cd Validation
    composer install

运行测试

    cd Validation
    vendor/bin/phpunit -c test/phpunit.xml test/

许可证

此软件库发布于BSD 3 Clause许可证下。

此软件库版权所有(c)2015-2020,Ashley Kitson,英国。

此软件库包含源自其他作品的代码项。

据我所知,所有包含的代码项都不违反主许可证,反之亦然。所以只要你坚持GPL V3+,就不用担心。如果不确定,请寻求适当的建议。

如果代码项的原始版权所有者反对这种包含,请联系作者。

谢谢

这不是我一人完成的。我深深地感激那些在我之前走过这条路的人。

以下人员为此库做出了贡献

Zend验证器:此库需要Zend验证器库。Zend验证器提供了一组针对特定用例的验证器。虽然此库提供了一些使用它们的特定示例,但它在此基础上构建。尽管如此,Zend验证器库是一个强大的工具,而这个开发者没有它是无法工作的。

Zend I18n:从Zend I18n库中可获得额外的验证。

历史

V1.0.0 初次发布

V1.1.0 更新依赖项

V1.1.1 将代码覆盖率移至codeclimate

V1.1.2 添加软件包链接

V1.1.3 验证PHP 7兼容性

V1.1.4 删除Lambda验证器的@internal标志

V1.1.5 允许更广泛的zend依赖关系

V1.2.0 添加额外的常用验证器

V1.2.1 更新依赖项

V1.2.2 更新构建脚本

V1.2.3 更新composer - 由Packagist composer.json格式更改强制

V2.0.0 BC中断。撤回旧php版本支持

V2.1.0 许可证从GPL V3更改为BSD 3 Clause

V3.0.0 BC中断。移除对PHP 7.2以下版本的支持。将Zend依赖项切换到Laminas