2011-11-01 77 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商店)。

希望這不是太複雜,你知道從哪裏去。當然,問問你是否需要澄清。

相關問題