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。如果失败,则返回一个 info(不是错误)
- 如果操作失败,则返回默认值。
- 最后,我们从 $_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 } }
获取消息
当我们验证一个对象时,它可以在 Message Container(也称为消息列表)中存储信息。
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
- 如果字段非空,则值非空,但可能是空的("").
$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 解决了datestring/datetimestring的问题。
- 2019-08-07 1.15
-
- 添加了类型datestring和datetimestring。它读取一个字符串,并将其转换为另一个字符串(作为日期或日期时间)。
-
- 代码格式化。
- 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原则)执行fetch操作。
-
- 添加了一个修复,当期望的值是数组,但返回单个值时的输入。
- 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和商业许可。
您可以在您的闭源项目中自由使用它。但是,如果您更改了这个库,则必须公开更改。