PHP表单验证

时间:2010-05-12 17:39:58

标签: php validation arrays field

毫无疑问,这个问题难以回答并以有道理的方式提出,但我会尽力而为:

我有一个表单,它使用PHP来显示表单的某些部分,例如:

<?php if ($_SESSION['EnrType'] == "Individual") { display only form information for individual enrollment } ?>

<?php if ($_SESSION['Num_Enrs'] > 6) { display only form information for 7 total members enrollment } ?>

在每个表单中,收集关于每个登记者的唯一信息,但每个登记者的基本标准是相同的,即所有登记者必须使用在FirstName字段中具有值。每个字段根据登记者编号命名,即Num1FirstName; Num2FirstName。

我有一个非常棒的PHP验证脚本,我不打算改变它,但我遇到的问题是脚本的重复,以便一次性验证所有字段。

提交时,所有POSTED项目都通过我的验证脚本运行,如果它们不相等,则根据规则集返回错误。

示例代码:

if (isset($_POST['submit']))
{
  // import the validation library
  require("validation.php");

  $rules = array(); // stores the validation rules

  //All Enrollee Rules
  $rules[] = "required,Num1FirstName,Num2FirstName,The First Name field is required.";

上面的脚本执行以下操作,$ rules [] =“REQUIREMENT,fieldname,error message” 如果需求提供标准(在这种情况下,只是传递一个值),fieldname是要验证的字段的名称,错误消息返回使用的错误。

我的目标是使用上面相同的公式并让$ rules []运行所有firstnames并返回仅在它们存在时发布的错误(即如果屏幕上不存在,则不检查成员#7的名字)。

如果我只是在'fieldnames'之间加一个逗号,那么只会检查第一个,然后是第二个,依此类推,所以这不会起作用。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

如果我理解你正在尝试做的事情:

<强> 1。定义类型
首先,您需要定义哪种类型的字段需要什么类型的规则,例如:

$type['FirstName']['requirement'] = 'required';
$type['FirstName']['error_message'] = 'The First Name field is required.';
// just random example: $type['MobilePhone']['requirement'] = 'optional'; $type['MobilePhone']['error_message'] = 'Only enter digits.';

<强> 2。浏览每个发布的值
其次,检查每个发布的值是什么类型的字段。现在$_POST数组中可能包含很多内容,您只需要检查某些字段。使用checkthis;1234;FirstName等名称作为输入字段可能会更容易。

foreach ($_POST as $key => $value) {
  // split the key, so you know what's what:
  $data = explode(';',$key);
// now $data[0] tells you what kind of field it is // $data[1] is the ID of the enrollee (your Num1, Num2) // $data[2] is the type of field
// only do checks for posted fields that start with "checkthis" if ($data[0]=='checkthis') { // now you can fill the $rule array: $rule[] = $type[$data[2]]['requirement'] . ',' . $key . ',' . $type[$data[2]]['error_message']; } }
这样,您在表单中包含的内容无关紧要。只要您定义了字段类型,如果规则数组包含在$ _POST值中,则规则将添加到规则数组中,您的验证脚本将完成剩下的工作。


修改
如果您构造输入字段,如下所示:


<input type="text" name="F1Firstname" value="" />
<input type="text" name="F2Firstname" value="" />
etc..

..并且您提交表单,$ _POST数组将例如看起来像这样:

//print_r($_POST) gives:

Array
(
    [F1FirstName] => John
    [F2FirstName] => Jane
)

..最简单的方法是使用foreach

遍历每一个
foreach ($_POST as $key => $value) {
  // first $key will be "F1FirstName"
  // first $value will be "John"

  // second $key will be "F2FirstName"
  // second $value will be "Jane"

  // etc
}

现在,$ _POST也将是其他类型的字段,例如F1MobilePhone或其他,需要不同的验证和不同的消息。因此,对于每个字段,您需要找出它是什么类型,以确定要在验证函数中输入什么类型的消息。一个选项是(这在foreach语句中):

if (strstr($key,'FirstName')) {
  // add a validation rule for the FirstName type
}
if (strstr($key,'Somethingelse')) {
  // etc
}

我不知道你的验证脚本是如何工作的,但我猜你正在做这样的事情:

// import the validation library
require("validation.php");

$rules = array(); // stores the validation rules

// All Enrollee Rules
$rules[] = "required,Num1FirstName,The First Name field is required.";

// Call on the validation function
$result = validate($rules);

然后你可能会收到回来,在这种情况下,“Num1FirstName”是否有效。由于您使用数组$rules,验证器可能一次处理多行。只需向数组添加更多值,但不要添加其他变量。如果你这样做:

$rules[] = "required,Num1FirstName,Num2FirstName,The First Name field is required.";

..验证器会认为“Num2FirstName”是错误消息,因为这是您输入的第3个值,并且它不知道如何处理现在为第4个值的实际消息。试试这个:

$rules[] = "required,Num1FirstName,The First Name field is required.";
$rules[] = "required,Num2FirstName,The First Name field is required.";

所以把所有这些结合在一起就可以了:

foreach ($_POST as $key => $value) {
  // first $key will be "F1FirstName"
  // first $value will be "John"

  // second $key will be "F2FirstName"
  // second $value will be "Jane"

  if (strstr($key,'FirstName')) {
    $rules[] = "required,$key,The First Name field is required.";
  }
  if (strstr($key,'Somethingelse')) {
    $rules[] = "required,$key,Some other message for this type of field.";
  }
}

// call on your validate function and feed it the $rules array you've created

将JavaScript添加到(预)验证是一个完全不同的故事。最后,你仍然需要在PHP中验证它,因为就像你说的那样,JS检查很容易被绕过。所以我想首先解决这个问题可能是最好的。