eftec/validationone

这是一个用于获取和验证字段的PHP库

2.9 2024-03-02 15:09 UTC

README

这是一个用于获取和验证字段,并根据条件将消息存储在不同的容器中(包括错误、警告、信息和成功)的PHP库。

该库背后的理念很简单:3个类,简单的依赖关系,并在PHP 7.1及更高版本中运行,因此可以在任何PHP项目中运行,包括WordPress、Laravel、核心PHP项目等。

Packagist Total Downloads Maintenance composer php php CocoaPods

完整图解

diagram full

目录

示例

示例

PHP表单和表格教程

diagram example
这是一个功能示例。一个典型的例子可能更复杂,即使只有几行代码。

概念

假设我们想验证一个名为"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>'); //\&lt;b\&gt;dog\&lt;                                                                                                       |
| htmldecode        |     | Decode from a html. It uses html_entity_decode()                                            | $this->conversion('htmldecode')->set('\&lt;b\&gt;dog\&lt;'); // \<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,则它们仍然有效。
  • 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 和商业版。

您可以在您的封闭源项目中免费使用它。但是,如果您更改此库,则必须披露更改。