danek / datafilter
Requires
- php: >=7.1.0
- ext-json: *
- ext-mbstring: *
Requires (Dev)
- phpunit/phpunit: ^9
This package is auto-updated.
Last update: 2024-09-25 11:07:08 UTC
README
DataFilter 是一个 PHP 数据验证(清理)模块。
内容
要求
- PHP 7.1+
通过 Composer 安装
要安装 danek/datafilter
的最新版本,请在 getcomposer.org 上使用 Composer。
composer require danek/datafilter
入门
一个基本示例,它期望两个 POST 参数,都是必需的
<?php require 'vendor/autoload.php'; // .. $profile = new \DataFilter\Profile([ 'attributes' => [ 'username' => true, 'password' => true ] ]); if ($profile->check($_POST)) { $data = $profile->getLastResult()->getValidData(); } else { error_log("Failed, required params not given"); }
深入了解
配置文件是 DataFilter 验证和过滤(清理)的核心。创建这些配置文件有三种可能的方式:使用内联 PHP 定义、使用用元语言(JSON 原生支持)编写的外部定义或使用程序化方法在运行时编码定义。
根据您的验证问题有多复杂,我认为使用内联 PHP 定义或将配置文件放在 JSON 文件中是一个好主意。在运行时,您可以相应地修改加载的配置文件。
验证配置文件
验证配置文件是一组属性,每个属性都有(可能多个)规则。您可以将其视为一个单独的表单,或者视为 Model(ORM..)的通用属性验证。
以下我将展示内联 PHP 方法(见上文)。
结构
$profile = [ // attribute definitions 'attibutes' => [ 'attributeName' => [ // rule definitions ], // list of attributes and rules ], // overwrite default invalid error message 'errorTemplate' => "Attribute :attrib: violated rule :rule:", // overwrite default missing error message 'missingTemplate' => "Attribute :attrib: is missing", // custom rule classes 'ruleClasses' => [ "\\MyRuleClass", // .. ], // custom filter classes 'filterClasses' => [ "\\MyFilterClass", // .. ], // custom, global pre-filters (before validating) 'preFilters' => [ function($in) { return $in; }, "namedFilter", ["\\SomeClass", "someMethod"], // .. ], // custom, global pre-filters (after validating, only on valids) 'postFilters' => [ function($in) { return $in; }, "namedFilter", ["\\SomeClass", "someMethod", // .. ] ];
规则格式
简单(必需的,可选的)
最简单的规则格式是 true
(必需)或 false
(可选)。
// .. 'attibutes' => [ 'attribName' => true, 'attribName2' => false ], // ..
命名检查函数
有几个预定义的命名函数可以用于。完整列表,请查看 \DataFilter\PredefinedRules\Basic
。
以下示例显示了一个正则表达式测试和一个最小长度测试。两个属性都是隐式必需的。
// .. 'attibutes' => [ 'attribName' => 'Regex:/^a[0-9]+', 'attribName2' => 'MinLen:5' ], // ..
包含预定义规则的类可以添加。它们必须实现返回函数引用的公共、静态方法
class MyClass { public static function ruleMyTest($arg1, $arg2) { return function ($input, \DataFilter\Rule $rule = null, \DataFilter\Attribute $attrib = null, \DataFilter\Profile $profile = null) { return true; } } }
自定义类需要注册,并且可以使用方法名使用
// .. 'ruleClasses' => ['\\MyClass'], 'attibutes' => [ 'attribName' => 'MyTest:foo:bar' ], // ..
自定义检查函数
可以内联添加自定义检查函数(可以是 Closure 或可调用的数组)
// .. 'attibutes' => [ 'attribName' => ['\\MyClass', 'myMethod'], 'attribName2' => function($input, ..) { return true; } ], // ..
复杂格式
复杂格式支持对每个属性和规则的严格控制。也可以为每个属性使用多个规则。
'attibutes' => [ 'attribName' => [ // whether required 'required' => true, // whether any (first) positive rule match validates argument (default: false) 'matchAny' => false, // default value is set if attribute NOT given (empty input is still given!). Implies optional (not required) 'default' => null, // default missing error text 'missing' => 'This attribute is missing', // whether skip all (global and local) filters (default: false) 'noFilter' => false, // list of ules 'rules' => [ 'ruleName' => [ // either a Closure (or callable array or a named function) 'constraint' => $constraint, // custom error message if rule fails 'error' => 'On error show this message', // whether ignore this rule on empty input 'skipEmpty' => false, // whether this rule sets the result valid and stops further rules 'sufficient' => false ] ], // dependencies: see explanation below 'dependent' => [ 'onSomeInput' => ['otherField1', 'otherField2'] ] ] ]
属性依赖
依赖关系最好通过常见的密码案例来解释。假设您有一个表单,其中有一个名为 password
的输入和一个名为 password_new
的输入。如果 password
已给出,则 password_new
也应该如此。在这种情况下,您将创建一个从 password
到 password_new
的依赖关系,如下所示
'attibutes' => [ // the password input 'password' => [ // not required itself 'required' => false, // .. 'dependent' => [ '*' => ['password_new'] ] //.. ], // default: password_new is optional 'password_new' => false, // .. ]
dependent
的左侧值表示其他属性(右侧数组)所依赖的输入。 *
是一个特殊案例,表示:“在任何输入上”。如果有多个依赖项给出,则在没有其他匹配项的情况下使用 *
。
此外,还有 dependentRegex
,它们的工作方式相同,但左侧有正则表达式。
'attibutes' => [ // the password input 'password' => [ // .. 'dependentRegex' => [ '/./' => ['password_new'] ] //.. ], // default: password_new is optional 'password_new' => false, // .. ]
在条件表单部分(例如,如果单选输入切换表单的一部分)的上下文中,依赖关系可能很有用。
使用 JSON
您可以将定义放在 JSON 文件中,并将它们加载到配置文件中。
{ "attibutes": { "someAttrib": true, "otherAttrib": { "required": false, "rules": { "isEmail": "Email", ... } }, ... }, "preFilters": [ "trim", ... ], ... }
然后加载定义
$profile = \DataFilter\Profile::loadJson("def.json");
将定义外包在 JSON 文件中的问题是,您不能使用可调用的函数(function() {...}
)。但是,使用下面描述的程序化方法,您可以在运行时添加这些规则/过滤器。
程序化
此选项应主要用于在运行时修改预定义配置文件,如有需要。您也可以从头创建完整的配置文件,但在我看来,这只会让代码更加混乱。
// creating $profile = new \DataFilter\Profile(); $profile->setAttrib('email'); $email = $profile->getAttrib('email'); $email->setRule('checkMail', 'Email'); $email->setRule('checkSomething', function($in) { return strlen($in) > 4 && preg_match('/aaa/', $in); }); $email->addPostFilters([ function($in){ return ucfirst($in); } ]); # .. // manipulating $profile = \DataFilter\Profile::fromJson("def.json"); $email = $profile->getAttrib('email'); # ..