我正在PHP中构建一个表单。我知道如何显示表单,然后从$_POST变量中获取提交的值,我知道如何验证这些变量,并根据输入显示"Thank You"或"Error"页面。
我不知道怎么做,虽然,是创建一个类似客户端的系统,其中,尽管我的用户点击"后退"按钮,一个单独的屏幕,然后我可以采取我从第一次提交收集的信息,并显示动态错误消息,如"请提供一个有效的电子邮件地址"或"名字是必填字段"旁边输入错误的字段。我还想检索任何以前提交的有效数据,并将其填充到表单中,这样用户就不会因为丢失他们输入的所有内容而感到沮丧。
在PHP中完成这样的事情的正确方法是什么?我最初认为,如果我可以传回一个带有input type="hidden"标签的错误消息数组,那么我就可以用PHP动态地提取我的值并显示消息,但是我一直被这种方法所困。
您可以在php会话中添加错误,但这会给打开多个浏览器选项卡的用户带来问题。
我的首选方法是将表单提交到同一页面,并将错误直接放在该页上,这样用户就不必单击后退按钮。这样就可以直接在表单中突出显示字段(将背景或轮廓设置为红色或类似的颜色)
<input type="text"
<?php (empty($_POST['field']?'style="backgroung-color: red;"':''))?>
name="field" value="<?php echo $_POST['field']?>" />
您可以输入<input type="text" name="field" value="<?php echo $_POST['field']?>" />
以获得旧值。
因为根据定义,网络是无状态的,所以当用户按下后退按钮时,没有真正好的方法来跟踪用户的行为。有一些黑客使用隐藏iframe工作,但这是更麻烦的方式,你正在寻找的
不要把客户端逻辑和服务器逻辑混在一起。完全相同的脚本可以输出表单并接受表单的输入。如果输入成功验证,则继续执行。如果没有,它将再次显示表单,这次显示错误消息和已经输入的数据。
下一次用户提交表单时,再次开始验证,直到成功通过。
因此,您首先使用输入值和错误消息扩展表单,但只有在标记为/set时才显示它们。
这可以通过$_POST
旁边的额外变量来完成-或者如果你喜欢它-通过使用一个框架的完整的表单抽象,如zend框架(这可能是你喜欢做的开销)或仅仅使用一个库/组件,如流行的HTML_QuickForm2。
这是一些非常简单的代码来演示整个方法,如果您使用库,它会更好(并且您不必编写代码,而是可以专注于实际的形式,如顶部的定义)。这段代码更多的是用于阅读和理解流程,而不是用于使用,我很快地输入了它,所以它(肯定有)语法错误,它的功能不完整,不适合一个完整的表单。这个只有一个电子邮件字段,甚至没有提交按钮:
/* setup the request */
$request->isSubmit = isset($_POST['submit']);
/* define the form */
$form->fields = array
(
'email' => array
(
'validate' => function($value) {return filter_var($value, FILTER_VALIDATE_EMAIL);},
'output' => function($value, $name) {return sprintf('<input type="text" value="%s" id="%s">', htmlspecialchars($value), htmlspecialchars($name)},
'default' => 'info@example.com',
),
);
/**
* Import form data from post request
*
* @return array data with keys as field names and values as the input strings
* or default form values.
*/
function get_form_post_data($form, $request)
{
$data = array();
foreach($form->fields as $name => $field)
{
$data[$name] = $field->default;
if ($request->isSubmit && isset($_POST[$name]))
{
$data[$name] = $_POST[$name];
}
}
return $data;
}
/**
* Validate form data
*/
function validate_form_data($form, $data)
{
foreach($form->fields as $name => $field)
{
$value = $data[$name];
$valid = $field['validate']($value);
if (!$valid)
{
$form->errors[$name] = true;
}
}
}
function display_form($form, $data)
{
foreach($form->fields as $name => $field)
{
$value = isset($data[$name]) ? $data[$name] : '';
$hasError = isset($form->errors[$name]);
$input = $field['output']($name, $value);
$mask = '%s';
if ($hasError)
{
$mask = '<div class="error"><div class="message">Please Check:</div>%s</div>';
}
printf($mask, $input);
}
}
// give it a run:
# populate form with default values -or- with submitted values:
$form->data = get_form_post_data($form, $request);
# validate form if there is actually a submit:
if ($request->isSubmit)
{
validate_form_data($form, $form->data);
}
# finally display the form (that can be within your HTML/template part), works like echo:
display_form($form, $form->data)
使用表单提交到同一页面,如果表单验证,使用标题将用户重定向到感谢页面。
header("Location: thank-you.php");
如果表单验证失败,您可以很容易地在同一页面上显示所有错误。