Php 有效的数据验证

Php 有效的数据验证,php,validation,Php,Validation,处理数据验证的有效方法是什么,比如表单提交 最初,我有一堆if语句,它们检查每个值并收集数组中的无效值,以供以后检索(并列出) 接下来我做的是创建一个类来处理各种数据验证场景,并将结果存储在一个内部数组中。数据验证完成后,我将检查是否出现任何错误,并进行相应处理: class Validation { private $errorList = array(); public function isAlphaNumeric($string, $field, $msg = '')

处理数据验证的有效方法是什么,比如表单提交

最初,我有一堆
if
语句,它们检查每个值并收集数组中的无效值,以供以后检索(并列出)

接下来我做的是创建一个类来处理各种数据验证场景,并将结果存储在一个内部数组中。数据验证完成后,我将检查是否出现任何错误,并进行相应处理:

class Validation
{
    private $errorList = array();

    public function isAlphaNumeric($string, $field, $msg = '')
    {
        if (!preg_match('/^[a-z\d]+$/i', $string))
        {
            $this->errorList[$field] = $msg;
        }
    }

    // more methods here

    public function creditCard($cardNumber, $field, $msg = '')
    {
        // Validate credit card number
    }

    // more methods here

    public function hasErrors()
    {
        return count($this->errorList);
    }
}

/* Client code */

$validate = new Validation();
$validate->isAlphaNumeric($fieldvalue1, $fieldname1, 'Please only use letters and numbers for your street address');
$validate->creditCard($fieldvalue2, $fieldname2, 'Please enter a valid credit card number');

if ($validate->hasErrors())
{
    // Handle as appropriate
}
当然,没过多久,这个类就变得臃肿起来,几乎可以验证无限类型的数据。我现在所做的是使用decorator将不同类型的数据分离到它们自己的类中,并仅在需要时调用它们,将通用验证(即isAlphaNumeric())留在基类中:

class Validation
{
    private $errorList = array();

    public function isAlphaNumeric($string, $field, $msg = '')
    {
        if (!preg_match('/^[a-z\d]+$/i', $string))
        {
            $this->errorList[$field] = $msg;
        }
    }

    // more generic methods here

    public function setError($field, $msg = '')
    {
        $this->errorList[$field] = $msg;
    }

    public function hasErrors()
    {
        return count($this->errorList);
    }
}

class ValidationCreditCard
{
    protected $validate;

    public function __construct(Validation $validate)
    {
        $this->validate = $validate;
    }

    public function creditCard($cardNumber, $field, $msg = '')
    {
        // Do validation
        // ...
        // if there is an error
        $this->validate->setError($field, $msg);
    }

    // more methods here
}

/* Client code */

$validate = new Validation();
$validate->isAlphaNumeric($fieldvalue, $fieldname, 'Please only use letters and numbers for your street address');

$validateCC = new ValidationCreditCard($validate);
$validateCC->creditCard($fieldvalue2, $fieldname2, 'Please enter a valid credit card number');

if ($validate->hasErrors())
{
    // Handle as appropriate
}

我走对了吗?还是我只是让数据验证变得比我需要的更复杂?

这对我来说太复杂了

数字数据:只需转换$\u POST值

$val=(int)$_POST["val"];
电子邮件:有预制作的功能可以做到这一点(希望找到一个正确的)

姓名和地址:什么都不要做,因为总有一天陌生人会输入一个你没有想到的unicode字符,然后被你的函数过滤掉

电话号码:什么都不要做,如果他想给一个假号码,他无论如何都会这样做


特殊代码,如post代码和类似的东西:通常你会有一个非常严格的标准,创建一个使用该标准进行过滤的函数,然后你就完成了。

如果有任何问题,那就是验证不够。要读取$\u POST和$\u GET中的数据,您至少需要:

  • 检查它是否存在(数组\u键\u存在)
  • 检查它是否是数组
  • 如果需要UTF-8,请检查它是否为有效的UTF-8(与“u”修饰符的preg_匹配是一个选项)
  • 然后针对字段类型进行验证
顺便说一下,当前在PHP中进行验证和消毒的方法是使用。在您的具体案例中,以下是一个示例:

<?php
$data = array(
    "arg1good" => "sdgdf790",
    "arg1bad"  => "sdgdf7/90",
    "arg1bad2" => array("sdgdf90", "sfdssf"),
    "arg2good" => "4567576456",
    "arg2bad"  => "45675764561",
);

$validateCredCard = function ($cc) {
    if (preg_match('/^\\d{10}$/', $cc))
        return $cc;
    else
        return false;
};

$arg1filt = array('filter'  => FILTER_VALIDATE_REGEXP,
                  'flags'   => FILTER_REQUIRE_SCALAR,
                  'options' => array('regexp' => '/^[a-z\d]+$/i'),
                  );
$arg2filt = array('filter'  => FILTER_CALLBACK,
                  'flags'   => FILTER_REQUIRE_SCALAR,
                  'options' => $validateCredCard,
                  );
$args = array(
    "arg1good" => $arg1filt,
    "arg1bad"  => $arg1filt,
    "arg1bad2" => $arg1filt,
    "arg2good" => $arg2filt,
    "arg2bad"  => $arg2filt,
);

var_dump(filter_var_array($data, $args));

你似乎不太清楚你的目标是什么——绩效?新代码的简单性?总体可维护性

当然,出于性能原因,我建议将验证作为代码进行维护,而不是将正则表达式(和阈值,以及……)存储为数据。问题似乎在于如何将您拥有的数据项映射到适当的验证。虽然可以将静态映射设置为数组,但还需要了解数据结构以呈现表单并映射到数据库列,也许您应该考虑在代码中实现更正式的元数据管理方法。

C.

@Lo'oris 你关于铸造价值观的回答并不完全完整。请考虑以下例子:

$val_1 = (int)null;    // $val_1 equals 0
$val_2 = (int)false;   // $val_2 equals 0
$val_3 = (int)'';      // $val_3 equals 0
$val_4 = (int)array(); // $val_4 equals 0
如本例所示,仅当您希望变量为大于0的整数时,此策略才有效

就“检查电子邮件”功能而言,你是正确的,在互联网上可以找到许多实现,但大多数都不完整或不正确

大多数实现都使用如下正则表达式:

"^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$"
"^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$"
或者这个:

"^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$"
"^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$"
这两个正则表达式都拒绝这样的电子邮件地址:

Abc\@def@example.com
customer/department=shipping@example.com
!def!xyz%abc@example.com 
有效(根据)

请看一下:

我也使用了与上一篇文章中描述的相同的方法。我也有兴趣得到这个问题的答案。现在我也在验证一个表单。我使用TryParse和其他内置函数。剩下的我自己创造。我不理解你关于施法的观点:是的,那些不正确的值将被施法到0。。。我很好!如果“你”需要更严格的东西,比如>0,那么,就这么说,然后编写代码,这不是需要解释的东西。。。
Abc\@def@example.com
customer/department=shipping@example.com
!def!xyz%abc@example.com