fishfin / php-valigator
独立的PHP类,用于数据清理和验证
Requires
- php: 5.5.* || 5.6.* || 7.*
This package is auto-updated.
Last update: 2024-09-11 21:07:35 UTC
README
极简主义爱好者们,欢呼吧!Valigator是一个独立的PHP类,用于数据清理和验证。它没有库依赖,实现了程序员友好的过滤器语法,并且非常灵活。它只是一个单独的类文件,包含它,你就可以开始了!
Valigator,嗯?
PHP API框架正在快速发展。它们非常简洁,快速,并且比功能强大但有时笨拙的大型框架更受欢迎。为了在API框架和项目中实现验证,必须安装大型供应商源,这会增加代码库的不必要增加和复杂性。Valigator就是为了解决这个问题而创建的。没有什么可以阻止你在非API项目中使用Valigator。向前走吧,你会喜欢的!
Valigator清单
✓ PHP (5.5.*, 5.6.*, 7.*)
✓ Stand-alone
✓ Data Sanitization
✓ Data Validation
✓ Simple
✓ Flexible
✓ Programmer-friendly
PS:Slim Framework 3很棒!
又一个Vali[dg]ator
也许吧。也许不是。是的,Valigator从一些好的,不,伟大的东西中汲取了灵感,并添加了自己的好东西。只是为了吸引你的兴趣:过滤器别名、多个参数、自定义标签、自定义验证错误消息等等。
Valigator的结构
术语
- 字段
映射到过滤器的数据的名称。通常是POST请求中的变量名称。字段可以映射到零个、一个或多个清理过滤器。字段可以映射到零个、一个或多个验证过滤器。区分大小写。例如,loginId
与loginid
不相同。 - 值
运行过滤器的字段的值。通常是映射到POST请求中的变量名称。除非通过运行在其上的过滤器使其不区分大小写,否则区分大小写。例如,email
过滤器不在乎传递的值是大小写字母。 - 过滤器
一些人称之为规则,Valigator更愿意称之为过滤器。因为存在清理过滤器和验证过滤器,所以很简单。不区分大小写。例如,误将required
误写成Required
没有任何区别。 - 参数
传递给过滤器的参数。您可以向过滤器传递零个、一个或多个参数。不区分大小写,除非需要过滤器使其区分大小写。例如,startswith
过滤器可以验证字段值是否以作为区分大小写参数传递的字符开头。 - 清理
清理过滤器简称为“清理”。清理从不失败,因此从不发出任何错误消息。 - 验证
而验证过滤器简称为“验证”。验证要么通过要么失败。如果失败,它将发出一个错误消息。 - 标签
程序员可以设置的字段的可读标签。如果没有设置,标签默认为字段变量名称的大写单词。例如,字段loginId
默认将标记为Login Id
(很酷,不是吗!),但可以被程序员重命名为已注册登录 ID
。以下模式的变量名称会自动检测:snake_case、camelCase、PascalCase和train-case。一些默认标签示例 token
变为Token
project_title
变为Project Title
book-1
变为Book 1
debitCardNumber
变为Debit Card Number
FAQAnswer6
变为FAQ Answer 6
SuspenseAccount#
变为Suspense Account #
- errormsg
验证产生的错误消息(每个验证一个)。程序员可以根据字段和验证自定义错误消息。错误消息可能包含一些特殊标签,这些标签将被动态替换 {field}
或{label}
将被替换为字段的标签{fieldlineage}
或{labellineage}
将被替换为完整字段层次结构的标签(反向顺序,例如Node 3 of Node 2 of Node 1
){fieldlineagef}
或{labellineagef}
将被替换为完整字段层次结构的标签(正向顺序,例如Node 1.Node 2.Node 3
){value}
将被替换为字段的值{filter}
将被替换为过滤器的名称{args}
或{parms}
将被替换为连接的参数字符串{arg1}
、...、{argn}
或{parm1}
、...、{parmn}
如果存在,将被替换为过滤器的单独参数(注意没有{arg0}
或{parm0}
)
齿轮和轮子
让我们用一个例子来更容易地从这里开始。假设我们想要验证以下字段
- loginId:必填,且必须是电子邮件ID
- name:必填,且必须是一个名字
- creditCardNumber:非必填,但如果提供,必须是有效的信用卡号码
- billAddressPINCode:非必填,但如果提供,必须是一个6位数字
- shipAddressPINCode:非必填,但如果提供,必须是一个6位数字
是的,你已经注意到了,驼峰命名法只是我的偏好。
现在假设我们正在一个数组中接收以下数据(如果你没有以数组的形式接收数据,你需要创建一个数组)
<?php // iteration 1 $inputData = [ 'salutation' => 'Mr.', // we aren't interested in validating this 'loginId' => '', // invalid data as it is empty // notice that 'name' is missing 'creditCardNumber' => '0001-0001-0001-ABCD', // not a valid credit card number // notice that 'billAddressPINCode' is missing // notice that 'shipAddressPINCode' is missing ];
现在根据我们有的数据验证要求创建过滤器,并添加一些其他有用的东西。请阅读代码注释中的重要说明。
<?php $myFilters = [ 'loginId:"Retail User ID"' => [ // overrides default label 'Login Id' 'sanitizations' => 'trim', // 'trim' is a popular filter, works exactly // like the PHP in-built trim() 'validations' => 'required|email', // multiple validation filters ], 'name:"Full Name"' => [ // overrides default 'Name' 'sanitization' => 'trim', // singular 'sanitization' works too 'validation' => 'required|personname', // singular 'validation' works too ], 'creditCardNumber' => [ // label defaults to 'Credit Card Number' 'sanitizations' => 'trim|numeric', // multiple sanitization filters 'validations' => 'creditcard', // if present, must be credit card number ], 'billAddressPINCode:"PIN Code (Billing)"|shipAddressPINCode:"PIN Code (Shipping)"' => [ // overrides default labels for Address PIN Codes // no sanitization filters here 'validations' => 'numeric|exactlen:6', // if present, must be numeric of exactly 6 // characters length ], ]; // Important Notes: // 1. 'loginId', 'name', 'creditCardNumber', 'billAddressPINCode' and 'shipAddressPINCode' are our // **fields** of interest // 2. Field names are case-sensitive: 'loginId' is not the same as 'loginid' // 3. Fields running same sanitizations and validations need not be listed separately, they can // be concatenated together with the pipe (|) delimiter // 4. Important understanding about filters: // a. Sanitization filters will modify input, and will never emit errors // b. Validation filters will never modify input, but can emit errors // 5. The order of running filters is as follows: // a. All sanitizations first (if they exist) in order: 'loginId' to 'billAddressPINCode' // b. Then all validations (if they exist) in order: 'loginId' to 'billAddressPINCode' // 6. If there are validation errors, they will be reported in exactly the same order, so // if you want some errors to be reported higher than the others, place the field higher // 7. You can use the following keywords interchangeably, whatever makes you comfortable: // a. 'sanitization' <=> 'sanitizations' // b. 'validation' <=> 'validations' // 8. Multiple filters can be set for each field, for sanitizations or validations, the // delimiter is '|'. Filters are run in the same order from left to right. Output of first // sanitization filter is passed to the second one, output of second to the third and so on. // Output of sanitization is sent to validation filters. // 9. For most validation filters except 'required', if input is absent or empty, validation // will pass. Simply add 'required' filter to the beginning of validation filters if the // value must be present.
现在让我们运行验证器
<?php require 'Valigator.php'; // point to the right path, or autoload $myValigator = new \Fishfin\Valigator($myFilters); $validationResults = $myValigator->run($inputData); // run() does sanitizations, then validations if ($validationResults === FALSE) { // at least one validation failed $myValidationErrorsArray = $myValigator->getValidationErrors(); } else { // all validations passed $sanitizedInputData = $validationResults; } // For iteration 1, following will be the results: // $validationResults: // FALSE // $myValidationErrorsArray: // ["Retail User ID is required", // "Full Name is required", // "Credit Card Number does not contain a valid credit card number"]
让我们尝试使用稍作修改的输入进行下一轮迭代。
<?php require 'Valigator.php'; // for brevity, we will not show this in next // iteration // iteration 2 $inputData = [ 'salutation' => 'Mr.', // still not interested in validating this 'loginId' => 'user', // still not okay, not an email 'name' => 'Ruskin Bond 5', // what's a numeric doing in a name? 'creditCardNumber' => '0001-0001-0001-0001', // does not satisfy credit card last digit logic 'billAddressPINCode' => 'A123456', // not a numeric, not 6 digits 'shipAddressPINCode' => '987654', // looks good ]; $myValigator = new \Fishfin\Valigator($myFilters); // block start // for brevity, we will not show this block in next $validationResults = $myValigator->run($inputData); // iteration if ($validationResults === FALSE) { $myValidationErrorsArray = $myValigator->getValidationErrors(); } else { $sanitizedInputData = $validationResults; } // block end // Results for iteration 2: // $validationResults: // FALSE // $myValidationErrorsArray: // ["Retail User ID is not a valid email address", // "Full Name does not seem to contain a person's name", // "Credit Card Number does not contain a valid credit card number", // "PIN Code (Billing) may only contain numeric characters", // "PIN Code (Billing) must be exactly 6 characters long"] // Nice, yeah?
现在是第3轮迭代的时间
<?php // iteration 3 $inputData = [ 'salutation' => 'Mr.', // whatever 'loginId' => 'user@example.com', // looks okay now 'name' => 'Ruskin Bond ', // notice additional blank at the end 'creditCardNumber' => '4111=1111=1111=1111', // is actually a valid sample Visa CC number // notice '=' symbol instead of hyphens or blanks 'billAddressPINCode' => '1234567', // not 6 digits 'shipAddressPINCode' => '987654', // is good ]; // Results: // $validationResults: // FALSE // $myValidationErrorsArray: // ["PIN Code (Billing) must be exactly 6 characters long"] // No error on credit card number, because it was sanitized for numbers! More on this later.
最后...
<?php // iteration 4 $inputData = [ 'salutation' => 'Mr.', 'loginId' => 'user@example.com', 'name' => 'Ruskin Bond ', 'creditCardNumber' => '4111=1111=1111=1111', 'billAddressPINCode' => '123456', // looks good now 'shipAddressPINCode' => '987654', ]; // Results: // $validationResults: // TRUE // $sanitizedInputData: // {"salutation":"Mr.", // "loginId":"user@example.com", // "name":"Ruskin Bond", // "creditCardNumber":"4111111111111111", // "billAddressPINCode":"123456", // "shipAddressPINCode":"987654"} // Did you notice the name was sanitized by removing leading and trailing blanks? That was because // of the 'trim' sanitization. Notice how '=' was removed because of the 'numeric' sanitization. // All validations passed this time, phew!
铃铛和哨子
现在你已经熟悉了基础知识,让我们继续一些高级内容。它是高级的,但不用担心,语义非常简单!
多个过滤器
你已经知道如何运行多个过滤器:管道符号 '|'。
'filter1|filter2|filter3'
过滤器的参数
所有冒号后面的位置参数,由逗号分隔,能有多简单?
'filter1:arg1,arg2,arg3'
如果你是程序员,你会知道位置参数的预期内容。那就是你的线索。
验证过滤器的自定义错误消息
如果数据不符合过滤器,验证过滤器会发出默认错误消息。如果你不喜欢默认消息,请创建自己的!在参数之后,放一个分号,然后开始你的自定义错误消息,用单引号或双引号。
'filter1:arg1,arg2;"My very own validation error message!"'
'filter2;\'And I\'ll change this one\'s too!\''
注意filter2没有参数,所以不需要冒号。如果错误消息本身不包含任何特殊字符,如单引号、双引号、冒号或分号,那么你可能甚至不需要加引号!
带有特殊标签的自定义错误消息
如果你喜欢自定义错误消息,你会更喜欢这个。在验证错误消息中,{field}
、{value}
、{filter}
、{args}
、{arg1}
... {argn}
都是特殊标签。
'filter1:arg1,arg2;"{field} with value {value} failed filter {filter} with attributes {args}"'
'filter2:arg1,arg2;"Maybe {field} didn't like {filter} with that parameter {arg2}"'
为了好玩,假设验证过滤器被命名为 'wildfur',参数为 'yellow,striped'。假设它运行的字段是 'animal',其标签为 'Animal'(可以是自动设置或显式使用 'label' 键)且字段的值为 'cheetah'。
'wildfur:yellow,striped;"{field} with value {value} may not have liked {filter} with attributes {args}, especially {arg2}"'
将发出错误消息
'Animal with value cheetah may not have liked wildfur with attributes yellow, striped, especially striped'
注释单个过滤器
只需用一个斜杠注释掉一个过滤器,以便它不运行。我保证这将非常有用,特别是在调试时。
'/filter1:arg1f1;"This filter will not run"|filter2:arg1f2;"This filter will run"'
跳过过滤器块
在过滤器列表中使用特殊关键字 'skip'。
'filter1|skip|filter2:;"Skipping this and all after"|filter3:;"Skipping this too"'
'filter1|skip:all|filter2:;"Skipping this and all after"|filter3:;"Skipping this too"'
'filter1:;"Will run"|skip:2|filter2:"Skipping first"|filter3:;"Skipping second"|filter4:;"Will run"'
skip
和 skip:all
意思相同,随便你用哪个。
流行过滤器别名
一些流行的过滤器和一些参数有别名,因为不同的程序员以不同的名称记住它们,这就是你看到的编程怪癖。
alphabet
与alphabetic
相同boolean
与bool
相同integer
与int
相同numeric
与num
与number
相同string
与str
相同
此列表将根据流行反馈进行更新。
过滤器大全
清理过滤器
basichtmltags
删除所有HTML标签,除了基本标签如<a>
、<b>
、<blockquote>
、<br>
、<code>
、<dd>
、<dl>
、<em>
、<hr>
、<h1>
、<h2>
、<h3>
、<h4>
、<h5>
、<h6>
、<i>
、<img>
、<label>
、<li>
、<p>
、<span>
、<strong>
、<sub>
、<sup>
和<ul>
。email
从电子邮件ID中删除所有非法字符。float
从浮点数中删除所有非法字符。htmlencode
将HTML字符转换为它们的HTML实体,例如,将&
转换为&
,将'
转换为'
,将"
转换为"
,将<
转换为<
,将>
转换为>
。