PHP:处理表单数据的更好方法是什么?

时间:2011-11-01 02:17:36

标签: php forms

在我的网站上,我拥有可配置表单的用户帐户,这些表单允许用户更新从名字和姓氏到隐私设置的所有内容。我使用以下函数来使用该输入更新数据库。 (请注意,以下代码使用特定于WordPress的功能。)

function update_account() {
    global $current_user; get_currentuserinfo();
    require_once( ABSPATH . WPINC . '/registration.php' );

    $uid = $current_user->ID;

    // First Name
    if(isset($_POST['first_name']) && $_POST['first_name'] <> $current_user->first_name) {
        wp_update_user( array( 
            'ID' => $uid, 'first_name' => esc_attr($_POST['first_name'])
        ));
    }

    // ...and so on 43 more times...

}

这感觉就像处理表单的错误方式。当有多个用户和频繁更新时,这看起来会对服务器性能产生负面影响,因为每个字段的if-then-else条件,甚至不在特定页面上的字段,强制检查每个字段的输入。

此外,由于可以预期表格数据保持相对恒定,因此我添加了&lt;&gt;运算符,以防止函数更新没有任何更改的字段,但我怀疑这也意味着仍然会评估每个字段的更改。更糟糕的是,添加新字段 - 总共有44个字段 - 是一个笨重的过程。

处理表单数据的更好方法是什么?

2 个答案:

答案 0 :(得分:4)

使用此代码保留您将要处理的字段数组,并对其进行迭代。例如,如果所有属性都是字符串,则此方法有效。如果您使用不同的数据类型(如布尔标志)来处理不同于字符串的数据类型,您可能希望将它们分组到自己的数组中。

// All the fields you wish to process are in this array
$fields = array('first_name', 'last_name', 'others',...'others99');

// Loop over the array and process each field with the same block
foreach ($fields as $field) {
    if(isset($_POST[$field]) && $_POST[$field] != $current_user->{$field}) {
        wp_update_user( array( 
            'ID' => $uid, $field => esc_attr($_POST[$field])
        ));
    }
}

答案 1 :(得分:1)

您的实施中缺少很多东西。我不知道你允许用户操作什么类型的数据,但大多数通常都有某种要求是可以接受的。就像没有某些字符,不是空白等等。我没有看到任何验证发生,所以你如何处理可能不合需要的值?当你收到不良数据时会发生什么?如何通知用户坏数据并提示他们更正?

如果我们稍微抽象一下情况,我们可以提出概括并实施适当的解决方案。 基本上,表单字段[可以]具有默认值,用户指定的值[表单审阅],验证要求和验证错误[带消息]。表单是一个字段集合,在表单提交需要验证时,如果无效,则通过指示性纠正提示重新显示给用户。

如果我们创建一个封装上述逻辑的表单类,我们可以实例化并使用它来传递我们的控制器/视图。哎呀,我只是假设你使用的是模型/视图/控制器类型框架,我对wordPress并不熟悉,所以我不知道这是否完全适用。但原则仍然适用。在您同时显示或处理表单的页面上,这里有一些伪逻辑如何显示它。

function update_account()
{
    // initialize a new form class
    $form = new UserAccountInfoForm();
    // give the form to your view for rendering 
    $this->view->form = $form;
    // check if form was posted [however your framework provides this check]
    if(!Is_Post())
        return $this->render('accountform.phtml');
    // check if posted form data validates
    if(!$form->isValid($_POST))
    {
         // if the form didn't validate re-display the form
         // the view takes care of displaying errors, with the help of its
         // copy of the $form object
         return $this->render('accountform.phtml');
    }

    // form validated, so we can use the supplied values and update the db
    $values = $form->getValues(); // returns an array of ['fieldname'=>'value']
    // escape the values of the array
    EscapeArrayValues($values);
    // update db
    wp_update_user($values);
    // inform the user of successful update via flash message
    $this->flashMessage('Successfully updated profile');
    // go back to main profile page
    $this->redirect('/profile');

这使您的控制器相对干净,易于使用。该视图得到了一些爱和关心,利用$ form值正确显示表单。从技术上讲,您可以在表单类中实现一个方法来为您提供表单html,但为了简单起见,我只是假设您的表单html是在accountform.phtml中手动编码的,它只是使用$ form来获取字段信息

<form action='post'>
<label>first name</label> <input class='<?=$this->form->getElement('first_name')->hasError() ? "invalid":""?>' type='text' name='first_name' value="<?=$this->form->getElement('first_name')->getValue()"/> <span class='errmsg'><?=$this->form->getElement('first_name')->getError()?></span><br/>

<label>last name</label> <input class='<?=$this->form->getElement('last_name')->hasError() ? "invalid":""?>' type='text' name='last_name' value="<?=$this->form->getElement('last_name')->getValue()"/> <span class='errmsg'><?=$this->form->getElement('last_name')->getError()?></span><br/>

<label>other</label> <input class='<?=$this->form->getElement('other')->hasError() ? "invalid":""?>' type='text' name='other' value="<?=$this->form->getElement('other')->getValue()"/> <span class='errmsg'><?=$this->form->getElement('other')->getError()?></span><br/>

<input type='submit' value='submit'/>
</form>

这里伪代码依赖于表单类方法“getElement”,它返回指定字段名称的字段类实例(将在表单类的构造函数中初始化)。然后在字段类方法“hasError”和“getError”上检查字段是否正确验证。如果表单尚未提交,则返回false和空白,但如果表单已发布且无效,则在调用时,它们将在validate方法中正确设置。此外,“getValue”将返回用户在提交表单时提供的值,或者如果表单尚未提交,则返回实例化和初始化字段类时指定的默认值。

显然,如果你推出自己的解决方案,这个伪代码依赖于你必须实现的许多魔法 - 而且它肯定是可行的。但是,在这一点上,我将引导您使用Zend Framework Zend_Form组件。您可以自己使用zend框架组件,而不必使用整个框架和应用程序结构。您也可以从其他框架中找到类似的表单组件解决方案,但我不知道这些(我们在工作场所是Zend Framework商店)。

希望这不是太复杂,你知道从哪里开始。当然,只要问你是否需要澄清。