Php 如何创建具有客户端特征的服务器端表单提交脚本?

Php 如何创建具有客户端特征的服务器端表单提交脚本?,php,validation,Php,Validation,我正在用PHP构建一个表单。我知道如何显示表单,然后从$u POST变量中获取提交的值,我知道如何验证这些变量,并根据输入显示“谢谢”或“错误”页面 不过,我不知道如何创建一个类似客户端的系统,在这个系统中,尽管我的用户点击了“后退”按钮,但我仍然可以在一个单独的屏幕上获取我从第一次提交中收集的信息,并显示动态错误消息,如“请提供有效的电子邮件地址”或“名字是必填字段”在输入错误的字段旁边。我还希望检索任何以前提交的有效数据,并将其填充到表单中,这样用户就不会因为丢失输入的所有内容而感到沮丧 在

我正在用PHP构建一个表单。我知道如何显示表单,然后从$u POST变量中获取提交的值,我知道如何验证这些变量,并根据输入显示“谢谢”或“错误”页面

不过,我不知道如何创建一个类似客户端的系统,在这个系统中,尽管我的用户点击了“后退”按钮,但我仍然可以在一个单独的屏幕上获取我从第一次提交中收集的信息,并显示动态错误消息,如“请提供有效的电子邮件地址”或“名字是必填字段”在输入错误的字段旁边。我还希望检索任何以前提交的有效数据,并将其填充到表单中,这样用户就不会因为丢失输入的所有内容而感到沮丧


在PHP中实现这种功能的正确方法是什么?我原本以为,如果我可以用input type=“hidden”标记传回一组错误消息,那么我就可以用PHP动态地提取我的值并显示消息,但我一直坚持这种方法。

不要将客户端逻辑与服务器逻辑混在一起。完全相同的脚本可以输出表单并接受其输入。如果输入成功验证,它将继续。如果没有,它将再次显示表单,这次显示错误消息和已输入的数据

下次用户提交表单时,验证将再次开始,直到成功通过

因此,您首先使用输入值和错误消息扩展表单,但仅在标记/设置时显示它们

这可以通过使用
$\u POST
旁边的其他变量来实现,或者如果您喜欢,也可以通过使用来自框架的完整表单抽象来实现,比如zend框架(这可能会增加您所需的开销),或者只需使用库/组件,比如流行的

编辑:

这是一些非常简单的代码来演示整个方法,如果您使用一个库,它会更好(而且您不必编写代码,相反,您可以专注于实际的形式,如上面的定义)。这段代码更多的是用于阅读和理解流程,而不是用于使用,我很快键入了它,因此它(肯定有)语法错误,对于一个完整的表单来说,它的功能并不完整。这一个只有一个电子邮件字段,甚至缺少“提交”按钮:

/* 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)
/*设置请求*/
$request->isSubmit=isset($_POST['submit']);
/*定义表单*/
$form->fields=数组
(
'电子邮件'=>数组
(
'validate'=>函数($value){return filter_var($value,filter_validate_EMAIL);},
'output'=>函数($value,$name){return sprintf('',htmlspecialchars($value),htmlspecialchars($name)},
'默认值'=>'info@example.com',
),
);
/**
*从post请求导入表单数据
*
*@return数组数据,键作为字段名,值作为输入字符串
*或默认表单值。
*/
函数get\u form\u post\u data($form$request)
{
$data=array();
foreach($form->fields as$name=>$field)
{
$data[$name]=$field->default;
如果($request->isSubmit&&isset($\u POST[$name]))
{
$data[$name]=$\U POST[$name];
}
}
返回$data;
}
/**
*验证表单数据
*/
函数验证表单数据($form$data)
{
foreach($form->fields as$name=>$field)
{
$value=$data[$name];
$valid=$field['validate']($value);
如果(!$有效)
{
$form->errors[$name]=true;
}
}
}
函数显示\u表单($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';
如果($hasError)
{
$mask='请检查:%s';
}
printf($mask,$input);
}
}
//试一试:
#使用默认值填充表单-或使用提交的值填充表单:
$form->data=get\u form\u post\u data($form$request);
#如果确实存在提交,则验证表单:
如果($request->isSubmit)
{
验证表单数据($form,$form->data);
}
#最后显示表单(可以在HTML/模板部件中),其工作原理类似于echo:
显示表单($form,$form->data)

不要将客户端逻辑与服务器逻辑混用。完全相同的脚本可以输出表单并接受其输入。如果输入成功验证,它将继续。如果未成功验证,它将再次显示表单,这次显示错误消息和已输入的数据

下次用户提交表单时,验证将再次开始,直到成功通过

因此,您首先使用输入值和错误消息扩展表单,但仅在标记/设置时显示它们

这可以通过使用
$\u POST
旁边的其他变量来实现,或者如果您喜欢,也可以通过使用来自框架的完整表单抽象来实现,比如zend框架(这可能会增加您所需的开销),或者只需使用库/组件,比如流行的

编辑:

这是一些非常简单的代码来演示整个方法,如果你使用一个库,它会更好(你不需要编写它,相反,你可以专注于实际的形式,比如上面的定义)。这段代码更多的是用于阅读和理解流,而不是用于使用,我很快就键入了它(当然有)语法错误,完整表单的功能不完整。此表单只有一个电子邮件字段,甚至缺少“提交”按钮:

/* 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)
/*设置请求*/
$request->isSubmit=isset($_POST['submit']);
/*定义表单*/
$form->fields=数组
(
'电子邮件'=>数组
(
'validate'=>函数($value){return filter_var($value,filter_validate_EMAIL);},
'output'=>函数($value,$name){返回sprintf('',htmlspecia
header("Location: thank-you.php");