2011-11-01 98 views
3

在我的网站上,我有可用表单配置的用户帐户,允许用户更新从名字和姓氏到隐私设置的所有内容。我使用以下函数用该输入更新数据库。 (请注意以下代码使用WordPress特定的功能。)PHP:什么是更好的方式来处理表单数据?

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条件,甚至是不在特定页面上的字段,都会强制检查每个字段的输入。此外,由于表单数据可以保持相对恒定,因此我添加了运算符以防止函数更新没有任何更改的字段,但是我怀疑这也意味着每个字段仍然被评估为了改变。更糟的是,增加新的领域 - 总共有44个领域 - 是一个笨拙的过程。

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

回答

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]) 
     )); 
    } 
} 
+0

哦,这很有趣。我甚至可以从数据库生成数组以避免与源相混淆。这不是遍历每个领域,甚至不相关的领域?大型阵列会对CPU或内存产生重大影响吗? – fireundubh

+1

@fireundubh它只是迭代你在数组中定义的字段。但是如果它们没有被设置在'$ _POST'中,它们将在循环中被跳过,就像你已经用你的44'if()'语句一样。除非实际发现问题,否则我不会担心它的表现,然后调整它。 –

+0

为什么不反转它,并用'foreach($ _POST作为$ key => $ val)''检查'in_array($ key)'? –

1

你的实现中缺少很多东西。我不知道您允许用户操作哪些数据,但通常有一些要求可以接受。就像没有特定的字符,不是空白的等等。我没有看到任何验证发生,所以你如何处理可能不受欢迎的值?当你收到不好的数据时会发生什么?您如何通知用户这些不良数据并提示他们纠正?

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

如果我们创建一个封装上述逻辑的表单类,我们可以实例化并使用它传递我们的控制器/视图。糟糕,我只是假设你正在使用Model/View/Controller类型的框架,而我对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商店)。

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

相关问题