例如,从表单提交处理数据验证的有效方法是什么?
最初我有一堆if
语句检查每个值并在数组中收集无效值以供以后检索(和列表)。
// Store errors here
$errors = array();
// Hypothetical check if a string is alphanumeric
if (!preg_match('/^[a-z\d]+$/i', $fieldvalue))
{
$errors[$fieldname] = 'Please only use letters and numbers for your street address';
}
// etc...
我接下来要做的是创建一个处理各种数据验证方案的类,并将结果存储在内部数组中。数据验证完成后,我会检查是否发生了任何错误并进行相应处理:
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
}
当然,不久之后,这个课程变得臃肿,几乎无限类型的数据需要验证。我现在正在做的是使用装饰器将不同类型的数据分成它们自己的类,只在需要时在基类中留下通用验证(即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
}
我是否在正确的轨道上?或者我只是将数据验证复杂化,然后才需要?
答案 0 :(得分:2)
如果有的话,你没有足够的验证。要读取$ _POST和$ _GET中的数据,至少需要:
顺便说一句,目前在PHP中进行验证和清理的方法是使用filters。在您的具体情况下,这是一个例子:
<?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));
给出:
array(5) {
["arg1good"]=>
string(8) "sdgdf790"
["arg1bad"]=>
bool(false)
["arg1bad2"]=>
bool(false)
["arg2good"]=>
string(10) "4567576456"
["arg2bad"]=>
bool(false)
}
答案 1 :(得分:1)
您似乎并不十分清楚自己的目标是什么 - 表现?简单的新代码?总体可维护性?
当然,出于性能原因,我建议将验证保留为代码,而不是将正则表达式(以及阈值和......)存储为数据。问题似乎是如何将您拥有的数据项映射到适当的验证。虽然您可以将静态映射设置为数组,但由于您还需要了解数据结构以呈现表单并映射到数据库列,因此您可能应考虑在代码中实现更正式的元数据管理方法
℃。
答案 2 :(得分:0)
这对我来说似乎过于复杂。
数字数据:只需转换$ _POST值
$val=(int)$_POST["val"];
电子邮件:有预制功能可以做到这一点(希望找到一个正确的功能)。
$email=check_email($_POST["email"]) or die("Ha!");
姓名和地址:什么都不做,因为它会在陌生人进入你没想过的unicode角色的那一天到来,并被你的功能过滤掉。
电话号码:什么都不做,如果他想给出一个错误的号码,无论如何都会这样做。
特殊代码,例如邮政编码和类似的东西:你通常会有一个非常严格的标准,创建一个使用那个过滤的功能,你就完成了。
答案 3 :(得分:0)
@ 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的整数时才有效。
就“check_email”功能而言 - 你说在互联网上有许多实现是正确的,但大多数都是不完整或不正确。
大多数实现都使用像这样的正则表达式:
"^[_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