【问题标题】:How do I create a server-side form submission script that has client-side characteristics?如何创建具有客户端特征的服务器端表单提交脚本?
【发布时间】:2011-08-05 05:46:35
【问题描述】:

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

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

在 PHP 中完成这样的事情的正确方法是什么?我最初认为如果我可以通过输入 type="hidden" 标记传回一组错误消息,然后我可以提取我的值并使用 PHP 动态显示消息,但我一直卡在这种方法中。

【问题讨论】:

  • 我想我得到了你的大部分问题,除了“用户点击后退按钮”部分。当他们这样做时,你想发生什么?通常这种行为是由浏览器控制的。
  • 我的意思是我显示的屏幕上有一个 html 按钮,上面写着“返回”,该按钮是用 on.click="location=''" 编程的,然后我将它指向我的页面 URL。跨度>

标签: php validation


【解决方案1】:

您可以在 php 会话中添加错误,但这会给打开多个浏览器选项卡的用户带来问题。

我首选的方法是让表单提交到同一页面并将错误直接放在该页面上,这样用户就不必单击返回按钮。这样您就可以直接在表单中突出显示字段(使背景或轮廓变为红色或类似的东西。)

<input type="text" 
    <?php (empty($_POST['field']?'style="backgroung-color: red;"':''))?>
    name="field" value="<?php echo $_POST['field']?>" />

您可以输入&lt;input type="text" name="field" value="&lt;?php echo $_POST['field']?&gt;" /&gt; 来获取旧值。
因为根据定义,网络是无状态的,所以没有真正好的方法来跟踪用户在点击后退按钮时做了什么。有些黑客可以使用隐藏的 iframe,但这比您要寻找的麻烦更多。

【讨论】:

    【解决方案2】:

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

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

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

    这可以通过 $_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)
    

    【讨论】:

    • 所以,我正在做的基本结构如下所示:if (!isset($_POST['submit'])) { ?&gt; &lt;!--Form code goes here--&gt; &lt;?php else { //Form validation //If validation fails echo a message indicating errors and a button to go back, attempt to send currently collected data back to the form through &lt;input type='hidden'&gt; 如果我理解正确,我的脚本结构是否正确?如果是这种情况,我想我不明白如何将我的数据发送回表单以处理和显示消息。
    • @danichiu:我添加了一些代码,展示了如何将表单逻辑封装到函数中。这使得它更容易集成。这与您建议的isset($_POST['submit']) 原则基本相同,但使一切都更加模块化。使用库可以为您节省大量时间,不仅使用第一个表单,而且使用您将在生活中编码的任何其他表单。此外,如果您开始阅读库代码,您会学得更快。
    • 所以我想通了——我当前的表单已经提交到同一个页面,在阅读了这个线程上的一些答案后,我意识到我可以创建另一个 if 分支来重新显示表单如有必要,错误消息。感谢您花时间回答这个问题!你的代码看起来很有趣,所以我可能会回去尝试使用该封装重新实现。
    • 是的,基本上它总是一些 (if-) 分支和附加变量。你可以更好地封装东西(封装变化是一种说法),更容易完成和扩展自己的代码。玩得开心!
    【解决方案3】:

    使用表单提交到同一页面,如果表单验证,使用标题将用户重定向到感谢页面。

    header("Location: thank-you.php");
    

    如果表单验证失败,您可以轻松地在同一页面上显示所有错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多