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"
  • 值的类型是 整数,因此它只返回一个整数。它也可以是整数、小数、字符串、日期、日期字符串和布尔值
  • 我们添加一个条件,值必须等于(eq10。如果失败,则返回一个消息(作为 错误
  • 我们添加另一个条件,如果值必须等于(eq30。如果失败,则返回一个 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>'); //\&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 解决了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和商业许可。

您可以在您的闭源项目中自由使用它。但是,如果您更改了这个库,则必须公开更改。