eftec / validationone
这是一个用于获取和验证字段的PHP库
Requires
- php: ^7.4 || ^8.0
- ext-ctype: *
- ext-fileinfo: *
- ext-json: *
- eftec/messagecontainer: ^2.8
Requires (Dev)
- phpunit/phpunit: ^8.5.13
Suggests
- eftec/formone: Allows to create form and integrates with the validation
README
这是一个用于获取和验证字段,并根据条件将消息存储在不同的容器中(包括错误、警告、信息和成功)的PHP库。
该库背后的理念很简单:3个类,简单的依赖关系,并在PHP 7.1及更高版本中运行,因此可以在任何PHP项目中运行,包括WordPress、Laravel、核心PHP项目等。
完整图解
目录
示例
这是一个功能示例。一个典型的例子可能更复杂,即使只有几行代码。
概念
假设我们想验证一个名为"id"的输入值(get),我们可以这样做:
- 默认值是文本 "ERROR"
- 值的类型是整数,因此它只返回一个整数。它也可以是整数、小数、字符串、日期、日期字符串和布尔值
- 我们添加一个条件,值必须等于(eq)10。如果失败,则返回一个消息(作为错误)
- 我们添加另一个条件,如果值必须等于(eq)30。如果失败,则返回一个信息(不是错误)
- 如果操作失败,则返回默认值。
- 最后,我们从$_GET(URL参数)中获取"id"。
use eftec\ValidationOne; $val=new ValidationOne(); $r = $val->def('ERROR') ->type('integer') ->ifMissingThenDefault() ->condition("eq", "It's not equals to 10", 10) ->condition("eq", "It's not equals to 30 (info)", 30, 'info') ->ifFailThenDefault() ->get('id'); // <-- end of the chain
但错误在哪里?消息存储在 messageList 中
var_dump($val->messageList->allArray()); // here we show all messages of any kind of type. var_dump($val->messageList->errorCount); // returns the number of errors. var_dump($val->errorcount()); // returns the number of errors (alternative) var_dump($val->hasError()); // returns true if there is an error.
然而,我们也可以通过类型(错误、警告等)显示消息,并且只能显示具有特定标识符的消息。
var_dump($val->messageList->get('id')->allErrorOrWarning()); // All error or warning contained in the key "id".
为什么消息存储在某些结构中?简单地返回错误不是更简单吗?
答案是表单。假设我们有一个包含三个字段的表单。如果其中一个字段失败,则错误必须单独对每个字段可见。整个表单也可以有自己的消息。
启动链
链的开始通常在代码的末尾编写。
允许的方法有
- get():从$_GET读取值
- post():从$_POST读取值
- request():从$_REQUEST读取值
- getFile():从$_FILES读取值
- set():读取手动输入的值(变量或常量)
示例
$val=new ValidationOne(); $id = $val->type('integer')->get('id'); $id = $val->type('integer')->post('id'); $id = $val->type('integer')->request('id'); $id = $val->type('integer')->set('123','id'); $val=new ValidationOne(); $id = $val->type('integer')->get('id'); // $_GET['id'] $val=new ValidationOne('frm'); // we set a prefix for every reading. $id = $val->type('integer')->get('id'); // $_GET['frm_id']
添加新的条件
condition ($condition, $message = "", $conditionValue = null, $level = 'error', $key = null)
添加一个根据输入 类型 依赖的条件。
-
@param string $condition
数字:req,eq,ne,gt,lt,gte,lte,between,null,notnull
字符串:req,eq,ne,minlen,maxlen,betweenlen,null,notnull,contain,notcontain ,alpha,alphanum,text,regexp,email,url,domain
日期:req,eq,ne,gt,lt,gte,lte,between
日期字符串:req,eq,ne,gt,lt,gte,lte,between
布尔值:req,eq,ne,true,false
文件:minsize,maxsize,req,image,doc,compression,architecture,ext
函数
fn.static.Class.methodstatic
fn.global.function
fn.object.Class.method 其中object是一个全局 $object
fn.class.Class.method
fn.class.\namespace\Class.method -
@param string $message
消息可以使用以下变量 '%field'、'%realfield'、'%value'、'%comp'、'%first'、'%second'
-
@param null $conditionValue
-
@param string $level (error,warning,info,success)。错误级别。有关更多信息,请参阅 MessageContainer
-
@param string $key 如果键不为空,则通过键添加多个条件
-
@return ValidationOne
注意:如果值为null且isNullValid()为true,则忽略条件。如果值缺失且isMissingValid()为true,则忽略条件。如果值为空('')且isEmptyValid()为true,则忽略条件。如果值为空('')或null且isNullOrEmptyValid()为true,则忽略条件。isNullValid()、isMissingValid()、isNullOrEmptyValid()和isEmptyValid()在只想在值存在或已设置时验证值时很有用。
示例
$validation->def(null) ->type('integer') ->condition('eq','%field %value is not equal to %comp ',50) ->condition('eq','%field %value is not equal to %comp ',60) ->set('aaa','variable2');
类型
每种输入类型的条件类型。
条件类型。
示例
$validation->def(null) ->type('integer') ->condition('eq','%field %value is not equal to %comp ',50) ->condition('between','%field %value must be between 1 and 50 ',[1,50]) ->condition('eq','%field %value is not equal to %comp ',60) ->condition('eq','%field %value is not equal to %comp ',[60,200]) // eq allows a single or array ->condition('fn.static.Example.customval','the function does not work') ->condition('req') ->condition('lt',"es muy grande",2000,'warning') ->condition('eq','%field %value is not equal to %comp',50) ->condition('fn.static.Example.fnstatic','the static function does not work') ->condition('fn.static.\somespace\Someclass.methodStatic',null) ->condition('fn.global.customval','The global function does not work') ->condition('fn.object.example.fnnostatic','the function object does not work') ->condition('fn.class.\somespace\Someclass.method','The function some class does not work') ->condition('fn.class.Example.fnnostatic','la funcion class no funciona'); // ->condition('fn.static.Example.customval','la funcion no funciona') function customval($value,$compareValue) { return true; }
调用自定义函数
有时我们需要使用自定义条件。我们可以创建一个全局变量、一个静态函数,甚至是一个类内的方法。
创建的每个方法或函数都必须有两个参数(任何名称)
- $value 要评估的值。
- $compareValue 要比较的值(可选)
例如,如果我们需要评估某个ID是否不存在于数据库中怎么办?
$validation->condition('fn.global.idExist','The id already exist!')->get("id"); function idExist($id,$compare=null) { // select count(*) c from table where id=$id if($c>0) { return true; } else { return false; } }
注意:如果我们需要指定命名空间,则可以使用以下表示法:\namespace\SomeClass
$validation->condition('fn.global.customfn'); // global $validation->condition('fn.static.SomeClass.staticfn'); // calling a static method inside the class SomeClass. $validation->condition('fn.class.SomeClass.noStaticFn'); // method inside a class,it creates an instance of an object then it calls the method $validation->condition('fn.object.myObject.noStaticFn'); // method inside a class, it uses an instance called $myObject // global function function customfn($value,$compareValue) { // returns true or false } // static function $myObject=new SomeClass(); class SomeClass { public static function staticfn($value,$compareValue) { // returns true or false } public function noStaticFn($value,$compareValue) { // returns true or false } }
获取消息
当我们验证对象时,它可以将信息存储在消息容器(也称为消息列表)中。
MessageContainer (EFTEC/MessageContainer) 以层次结构方式包含消息列表
⭐ Container (usually only 1 for all the project) ⭐ Lockers (from zero to many) ⭐ Messages (from zero to many and grouped by level) $container->get('locker20')->firstError(); // it returns the first message of error in the locker20 that is part of the container.
消息按照以下级别划分
如何管理消息?
有关 MessageContainer 的更多信息,请参阅 EFTEC/MessageContainer
示例
$validation->addMessage('idlocker','this field is required','error'); // it adds a message inside a locker. $validation->messageList->get('idlocker')->allError(); // it gets all errors from the locker idlocker $validation->getMessages(true); // it gets all messages of error or warning from all the lockers.
处理日期
我们还可以处理日期。有几种日期格式类型。
指定日期格式的有两种方式,短(仅日期)和长(日期和时间)。我们可以指定输入和输出的格式。
$r=getVal()->type('datestring')->set('31-12-2019'); // 2019-12-31 note: the default input value is d/m/Y, not m/d/Y
我们可以通过更改字段或调用以下函数来更改日期格式
setDateFormat
设置日期格式(输入短,输入长,输出短和输出长)
$validation->setDateFormat('m/d/Y', 'm/d/Y H:i:s', 'Y-m-d', 'Y-m-d\TH:i:s\Z')
setDateFormatDefault
将日期格式设置为默认配置
$validation->setDateFormatDefault();
setDateFormatEnglish
将日期格式设置为
$validation->setDateFormatEnglish()
生成异常
默认情况下,此库不生成异常。然而,如果消息为ERROR类型和/或WARNING类型,则可以生成异常。
throwOnError()
使用此方法,如果容器生成错误,则还会生成一个新的异常。
注意:默认情况下,大多数消息都是ERROR类型。
注意:当操作符为throw时,则值未分配且堆栈被删除,即如果我们抛出异常,所有信息都会丢失。
try { $validation->type('integer') ->throwOnError() // for errors only ->set('hello', 'field1'); // or you could use: $validation->type('integer') ->throwOnError(true,true) // for errors and warnings ->set('hello', 'field1'); $this->fail('this value means the throw failed'); } catch(\Exception $ex) { $this->assertEquals('field1 is not numeric',$ex->getMessage()); }
处理缺失或空值
在此库中处理空值有四种不同的方式。
exist
- 如果字段或文件存在,则值存在,无论值或它是否为null或空。
- 如果设置exist()且值缺失,则引发错误。
$validation->exist()->set(null); // is valid. $validation->exist()->set(''); // is valid. $validation->exist()->get('field'); // is valid only if $_GET['field'] exist (even if it is null)
required
- 如果字段不为null或空,则值是必需的。必需等于null和空同时存在
$validation->required()->set(null); // is not valid. $validation->required()->set(""); // is not valid. $validation->required()->set('hi'); // is valid.
notnull
- 如果字段不为null,但可以是空(""),则值不是null。
$validation->notnull()->set(null); // is not valid. $validation->notnull()->set(""); // is valid. $validation->notnull()->set('hi'); // is valid.
notempty
- 如果字段不是''(长度为0的字符串),但可以是null,则值不是空。
$validation->notempty()->set(null); // is valid. $validation->notempty()->set(""); // is not valid. $validation->notempty()->set('hi'); // is valid.
允许缺失或空值
此外,还有4种方式接受缺失的值,null或空,绕过任何条件。
$validation->isNullValid()->condition(....)->set(null); // is valid no matter the condition. $validation->isNullorEmptyValid()->condition(....)->set(null); // is valid no matter the condition. $validation->isEmptyValid()->condition(....)->set(''); // is valid no matter the condition. $validation->isMissingValid()->condition(....)->get('field'); // If the field is missing, then is valid no matter the condition
当输入有值时,除非值缺失、空或null,否则我们需要验证时使用。
isNullorEmptyValid()等同于调用:isEmptyValid()->isNullValid()
此外,这些运算符可以堆叠。
$validation ->isNullorEmptyValid() ->isMissingValid() ->condition(....) ->set(....); // this expression is valid if the value is null, empty(''), the value is missing, no matter the conditions.
处理结果
def()
我们可以设置默认值。当出现错误时,此值可以作为回退使用。默认值不会被转换或处理。
$validation ->def(-1) ->type('integer') ->ifFailThenDefault() ->set(...); // if the operation fails, then it returns -1
trim()
修剪结果。默认情况下,结果不会被修剪。您可以修剪左侧、右侧或两侧。它使用convert()方法进行操作。
$validation->trim()->set(....); // trim both sided $validation->trim('trim','.,')->set(....); // trim . and , $validation->trim('ltrim')->set(....); // trim left sided $validation->trim('rtrim')->set(....); // trim right sided
alwaysTrim()
有时,我们总是想要修剪结果。因此,我们可以使用此方法始终修剪结果。它堆叠在转换的末尾。
$validation->alwaysTrim(); // always trim the next characters " \t\n\r\0\x0B" $validation->alwaysTrim(true,",."); // always trim , and . // ... $validation->alwaysTrim(false); // we disable the always trim.
isArray()
如果我们想要获取一个数组,那么我们可以使用下一个方法
$array=$validation->isArray()->request('id');
它也验证每个值。然而,它将消息存储在单个容器中。
如果我们想单独存储每个消息,那么我们可以使用
$array=$validation->isArray(true)->request('id');
数组示例
<form> <input type='text' name='field[col1][0]' value="cocacola" /> <input type='text' name='field[col2][0]' value="123" /><br> <input type='text' name='field[col1][1]' value="fanta" /> <input type='text' name='field[col2][1]' value="123" /><br> <input type="submit"><br> </form>
注意:您也可以将字段定义为'field[0][col1]',这样您就不需要反转数组
$values=getVal()->isArray(true)->request('field'); // ['col1'=>['cocacola','fanta'],'col2'=>[123,123]] ValidationOne::invertArray($values); // // [['col1'=>'cocacola','col2'=>123],['col1'=>'fanta','col2'=>123]]
invertArray()
如果值是数组,但列的索引与列反转,则可以反转顺序
示例
$arr=['col1'=>['cocacola','fanta'],'col2'=>[1,2]]; ValidationOne::invertArray($arr); // [['col1'=>'cocacola','col2'=>1],['col1'=>'fanta','col2'=>2]] ''' ### convert() It converts the end result after it is validated. Depending on the type of conversion, it allows up to 2 arguments. The conversion could be stacked so the order could matter. If the value is missing, or it is used the default value, then it is not converted. | Type | | Description | Example | |-------------------|-----|---------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | upper | | Converts the value in uppercase | $this->conversion('upper')->set('Hello World'); // HELLO WORLD | | lower | | Converts the value in lowercase | $this->conversion('lower')->set('Hello World'); // hello world | | ucfirst | | Converts the first character in uppercase | $this->conversion('ucfirst')->set('hello world'); // Hello world | | ucwords | | Converts the first character in a word in uppercase | $this->conversion('ucwords')->set('hello world'); // Hello World | | replace | | Replace a string by other | $this->conversion('replace','hello','world')->set('hello hello'); // world world | | sanitizer | | Sanitizer the result. It uses filter_var() | $this->conversion('sanitizer',FILTER_SANITIZE_EMAIL)->set('//aaa@bb.com'); // aaa@bb.com<br />$this->conversion('sanitizer',FILTER_SANITIZE_SPECIAL_CHARS,FILTER_FLAG_STRIP_HIGH) | | alphanumeric | | Sanitize the result by keeping the alphanumeric characters plus underscore : | this->conversion('alphanumeric')->set('HELLO world_-123'); // HELLOworld_123 | | alphanumericminus | | Sanitize the result by keeping the alphanumeric characters plus underscore and minus symbol | this->conversion('alphanumericminus')->set('HELLO world_-123'); // HELLOworld_-123 | | regexp | | It calls preg_replace to replace a text | this->conversion('regexp','/[/^0-9]/','')->set('hello123'); // 123 | | rtrim | | Trim the right characters | $this->conversion('rtrim') | | ltrim | | Trim the left characters | $this->conversion('ltrim') | | trim | | Trim the right and left. It is equivalent to $this->trim() | $this->conversion('trim')->set(' hello '); // hello<br />$this->conversion('trim'," \t\n\r\0\x0B") | | htmlencode | | Encode to html content. It uses htmlentities() | $this->conversion('htmlencode')->set('\<b>dog\</b>'); //\<b\>dog\< | | htmldecode | | Decode from a html. It uses html_entity_decode() | $this->conversion('htmldecode')->set('\<b\>dog\<'); // \<b>dog\</b> | ```php $validation ->convert('replace','hello','world') // world world ->convert('upper') // WORLD WORLD ->set('hello hello'); // stacking an operator. $validation->convert('upper')->set(....); $validation->convert('lower')->set(....); $validation->convert('ucfirst')->set(....); $validation->convert('ucwords')->set(....); $validation->convert('replace','hello','world')->set(....); // trim right sided $validation->convert('sanitizer',FILTER_SANITIZE_EMAIL)->set(....); $validation->convert('rtrim')->set(....); $validation->convert('ltrim')->set(....); $validation->convert('trim')->set(....); $validation->convert('htmlencode')->set(....); $validation->convert('htmldecode')->set(....);
版本列表
- 2024-03-02 2.9
- 更新依赖项到PHP 7.4。PHP 7.2的扩展支持已于3年前结束。
- 在代码中添加了更多的类型提示。
- 2023-11-13 2.8
- 一些维护代码。
- 2023-02-26 2.7
- 为isArray()添加了一个新参数
- 添加了静态方法invertArray()
- 2023-01-26 2.6
- 一些小的清理。
- 2022-08-27 2.5
- [更新] 添加了库中大多数函数的参数验证。
- 2022-03-11 2.4
- [更新] 添加了条件alphanumunder(字母数字或下划线)。
- 2022-02-05 2.3
- [更新] 将依赖项更新到MessageContainer 2.3。现在MessageContainer作为单例注入。
- [更新] ValidationOne方法现在具有类型提示(返回值)。
- [修复] inputDate()方法有一些错误操作。现在,它们已被移除。
- 2022-02-04 2.2
- [新增] 支持PHP 8.1。PHP 8.1相当复杂,它废弃了几个函数的许多参数。
- [新增] 此库支持PHP 7.2或更高版本。如果您需要旧功能,则可以使用旧版本。
- 2022-01-29 2.1
- [新增] 方法throwOnError()
- 2022-01-29 2.0.2
- 修复了当条件为"gte"时的问题。
- 2022-01-15 2.0.1
- 更新依赖项
- 2022-01-15 2.0
- PHP 7.1及更高版本。
- [核心] 许多清理
- 2021-03-18 1.30.1
- 在composer.json中更新了依赖项
- 2021-03-17 1.30
- 我们将库分为两个,一个用于验证(此库)另一个用于消息,称为eftec/MessageContainer。
- 2021-02-13 1.29
- 添加了trim()、alwaysTrim()、convert()、errorCount()和hasError()方法。
- 2021-02-10 1.28
- 添加了新方法isNullOrEmptyValid()
- 2021-02-10 1.27
- 添加了新方法isMissingValid()、isEmptyValid()和isNulLValid()
- 2021-02-09 1.26
- 新的验证和方法。
- exist()值必须存在(但它可以是null或空)
- required()现在它验证值是否不为null或空,但不验证值是否存在。
- notempty()
- 2021-01-07 1.25
- PHP 8.0已停止使用常量INPUT_GET、INPUT_POST和INPUT_REQUEST,因此我们将使用数字代替
- INPUT_POST = 0
- INPUT_GET = 1
- INPUT_REQUEST = 99 因此,如果您使用INPUT_GET、INPUT_POST或INPUT_REQUEST,则它们仍然有效。
- PHP 8.0已停止使用常量INPUT_GET、INPUT_POST和INPUT_REQUEST,因此我们将使用数字代替
- 2020-10-01 1.24.3
- 一个小清理。
- 2020-05-21 1.24.2
- 修复了条件与数组(当它被初始化时)的问题。
- 2020-05-21 1.24.1
- 修复了条件与数组的问题。
- 2020-05-21 1.24
- 清理
- 2020-04-07 1.23.2
- 解决了datetimestring和defnatural的问题
- 2020-04-07 1.23.1
- 解决了验证和输入问题。它未能验证。
- 解决了默认值是字符串而类型是datetimestring的问题。
- 2020-02-01 1.23
- 解决了在endConversion()中,当默认值为""或null(或不是DateTime对象),类型为"datetimestring",并且值缺失时的问题。
- 实际上所有方法都已测试。
- resetValidation()现在允许删除所有消息。
- 修复了验证"ne"。
- 2020-01-04 1.22
- 添加了新条件'mime'、'minetype'、'exist'、'notexist'等。
- 条件'eq'和'ne'允许一个简单的值或值数组。
- 2020-01-03 1.21
- ValidationOne::runConditions()现在允许(对于文件类型),条件架构和压缩
- ValidationOne::getFileExtension()现在可以返回扩展名为mime
- ValidationOne::getFileMime()新方法,返回文件的mime类型。
- 2019-11-27 1.20
- 修复了countErrorOrWaring->countErrorOrWarning的名称。
- 2019-11-27 1.19
- 添加了新字段 MessageContainer.errorOrWarning
- 添加了新方法 MessageLocker.countErrorOrWaring()
- 2019-10.01 1.18 添加了对 phpunit/phpunit 5.7 和 6.5 的兼容性
- 2019-10-01 1.17 修复了一个 bug。如果输入为零,则将其视为 null。
- 2019-08-10 1.16 解决了日期字符串/日期时间字符串的问题。
- 2019-08-07 1.15
-
- 添加了日期字符串和日期时间字符串类型。它读取一个字符串,并将其转换为另一个字符串(作为日期或日期时间)
-
- 代码格式化
- 2019-03-08 1.14 添加了 getFile() 来上传文件。
- 2018-12-15 1.13 添加了 phpunit 和 travis。
- 2018-10-29 1.12 getFile 现在可以通过 ValidationOne() 使用。
- 2018-10-22 1.11 一些修复。现在 isEmpty 被称为 isMissing
- 2018-10-22 1.10 新功能
-
- 添加了 ValidationInputOne,现在抓取操作由这个类完成(SRP原则)
-
- 添加了一个修复,当预期值为数组,但返回单个值时
- 2018-10-15 1.9 添加了一些额外功能
- 2018-10-15 1.8 一些修复和 phpdocs,一个新示例
- 2018-10-15 1.7 在 ValidationOne 中添加了 addMessage() 方法。现在 ErrorItem/ErrorList 被称为 MessageLocker 和 MessageContainer
- 2018-10-06 1.5 在 MessageLocker 中添加了 first() 方法
- 2018-10-03 1.4 添加了 defaultNatural()
- 2018-10-02 1.3 删除了 basicvalidation()。它已恢复。
- 2018-10-02 1.2 array() 现在是 isArray()
- 2018-09-30 1.1 一些修复
- 2018-09-29 1.0 第一个版本
待办事项
- 更多示例
- 文档
注意
它作为双重许可分发,LGPL-v3 和商业版。
您可以在您的封闭源项目中免费使用它。但是,如果您更改此库,则必须披露更改。