2008-11-13 60 views
4

我將如何去創建一個真實世界的表單創建類,我可以用它來顯示一個新的表單,不同類型的字段,我想要多少個字段,我可以使用下拉列表,我可以通過使用所有這些OOP?如何使用OOP動態構建PHP表單?

回答

7

你一定可以。考慮一個Form類,它存儲關於表單本身的信息:methodactionenctype屬性。還要在頂部插入可選標題和/或說明文字等內容。當然你也需要一組輸入元素。這些可能會被放到他們自己的類中(儘管爲InputText,InputCheckbox,InputRadio進行子類化可能會在頂部)。這裏有一個模糊的框架設計:

class Form { 
    var $attributes, // array, with keys ['method' => 'post', 'action' => 'mypage.php'...] 
     $heading, 
     $description, 
     $inputs  // array of FormInput elements 
    ; 

    function render() { 
     $output = "<form " . /* insert attributes here */ ">" 
       . "<h1>" . $this->heading . "</h1>" 
       . "<p>" . $this->description . "</p>" 
     ; 
     // wrap your inputs in whatever output style you prefer: 
     // ordered list, table, etc. 
     foreach ($this->inputs as $input) { 
      $output .= $input->render(); 
     } 
     $output .= "</form>"; 
     return $output; 
    } 
} 

的的formInput類將只需要存儲的基本知識,如類型,名稱,值標籤。如果您想變得棘手,那麼您可以應用驗證規則,然後在渲染時將其轉換爲Javascript。

8

說實話我不會推出自己的,考慮到PHP有幾個成熟的表單包。

對於PHP4站點,我使用PEAR的HTML_QuickForm包(http://pear.php.net/manual/en/package.html.html-quickform.php)。

對於PHP5,我會看看Zend_Form(http://framework.zend.com/manual/en/zend.form.html)。

對於我的quickform代碼,我使用了一個幫助類,它允許我使用配置數組定義表單。例如:

echo QuickFormHelper::renderFromConfig(array(
    'name' => 'area_edit', 
    'elements' => array(
    'area_id'   => array('type' => 'hidden'), 
    'active'   => array('type' => 'toggle'), 
    'site_name'   => array('type' => 'text'), 
    'base_url'   => array('type' => 'text'), 
    'email'    => array('type' => 'text'), 
    'email_admin'  => array('type' => 'text'), 
    'email_financial' => array('type' => 'text'), 
    'cron_enabled'  => array('type' => 'toggle'), 
    'address'   => array('type' => 'address'), 
), 
    'groups' => array(
    'Basic Details' => array('site_name', 'base_url'), 
    'Address Details' => array('address'), 
    'Misc Details' => array(), // SM: Display the rest with this heading. 
), 
    'defaults' => $site, 
    'callback_on_success' => array(
    'object' => $module, 
    'function' => 'saveSite', 
    ), 
)); 

注意上面的元素類型「地址」和「切換」實際上多個表單域(基本上,間類型)。這就是我喜歡這個幫助類的原因 - 我可以用他們的規則定義一組標準字段(例如地址,credit_card等),並且可以以一致的方式在很多頁面上使用它們。

1

僅供參考,Khurram Khan的Object Oriented Forms是用於PHP的優秀OO表單實現。

這裏是什麼樣的代碼看起來像一個示例:

$form = new Form("Register", "form.php"); 

$personal = new Block("Personal Information"); 

$name = new Text("name", "Your name"); 
$name->setDescription("this is my description"); 
$name->addValidator(new MaxLengthValidator("The name you have entered is too long", 30)); 

... 

另一種比較流行的實現是PHPlib。不過,我覺得這有點笨拙。看起來它只是一些包裝在一個類中的標準函數式編程。

另一個選擇是爲內置的DOM庫編寫一個抽象。這將允許您使用OO符號手動創建任何類型的表單和表單元素,還有額外的好處是您將返回一個OO DOM實例,該實例可用於程序中的其他位置。

1

我會在這裏反對其他建議,並建議您建立自己的庫來生成表單。如果你失敗了,你仍然會在這個過程中學到很多東西。

設計過程在這裏最重要。你從頂部開始,問自己一個表單上發生了什麼。在抽象層面上,表單充滿了元素。有些是可見的,有些是不可以的,有些可以由用戶輸入,但另一些則不能,一些元素可以觸發其他元素...並且列表繼續...最終你會得到「裝飾性」(文本,標題,分隔符,字段集,鏈接,圖像),交互式元素(輸入,下拉,複選框,單選按鈕,提交按鈕)以及最終元素既不是裝飾性的,也不是交互式的(隱藏輸入,錨和作爲容器來分組其他元素的元素)。

一旦你組織了不同的類別,你就可以開始研究所有元素具有的特徵,元素類。然後你沿着鏈子讓你的課越來越多,從其他更簡單的元素類繼承。在我的庫中,基本元素類稱爲form_element,每個form_element都有一個唯一的名稱,即同一個表單中的其他元素不能具有。 form_element也有一組屬性。它具有所有元素都調用render()的功能。在基類中,render()什麼也不做(因此基本元素總是不可見的),但是在派生類中,它開始生成HTML。順便說一句,我從來沒有讓我的任何課程創建HTML。相反,我有一個名爲html的靜態類,它爲所有需要其服務的類編寫HTML。

在表單元素鏈的早期階段,您應該有一個容器來組合其他容器。它應該有一個add()函數,它的render()函數應該包括調用其所有子元素的render()函數。表單類將從這個容器類派生。

在設計上花費大量的時間。注意與庫的其餘部分的兼容性。

如果您希望表單中的數據來自數據庫並保存爲一個數據庫,則需要添加此功能並將表單元素類鏈接到表和列。在這裏,我還有一個可以檢索/保存數據的獨立數據庫類。我有一個查詢類創建查詢。表單元素與創建HTML,創建查詢或訪問數據庫無關。我的靜態類DB和我的查詢類負責骯髒的工作。表單類應該只涉及表單內容。表單類將所有表和列的所有表和列收集到需要保存的字段中,並將其傳遞給查詢類,查詢類創建查詢,然後將查詢傳遞給執行它的數據庫類。

一旦你正確設置,看起來可怕的複雜突然變得非常容易,適當設計的類。因爲你有一個可以編寫HTML的類,所以你的表單類需要html :: init()並且跟在render()後面,表單的整個HTML代碼在html緩衝區中都是可用的。 html :: output()將所有東西都刷新。

驗證也使用靜態驗證類在外部處理。可以驗證的表單元素以可以直接傳遞給驗證類的格式保存數組中的驗證指令。每個需要驗證的元素都綁定到一個錯誤元素,如果元素沒有驗證,則會顯示錯誤,如果一切順利,則會保持不可見狀態。

這是爲了告訴你,當你設計一個表單環境(或其他)時,你真的需要在開始之前考慮一切。您投入的工作可能不會立即轉化爲可以爲您的應用程序提供支持的代碼,但它肯定會使您成爲更好的開發人員,從而使您將來的項目更容易處理。

表單類創建表單,html類創建HTML,查詢類使查詢和數據庫類處理數據庫。如果你的課程開始完成應該由不同課程完成的工作,那麼你就有設計問題。

下面是一個代碼示例,以顯示我的表單庫是如何工作的:

$fm = new form('myform'); 
$fm->binding(FORM_DATABASE); 
$fm->state(FORM_RETRIEVE); 
$fm->set_recno(1); 
$fm->add(new form_heading("My form")); 
$fm->add($el=new form_input("name",40)); 
$el->bind_data('mytable','mycolumn'); 
$el->set_attribute('size', 25); 
$el->set_default('Name'); 
$fm->add($el=new form_submit("submit_btn","Submit")); 
if($fm->manage()) 
{ 
redirect or do something else here. The interaction with the form is done. The initial state for the form was FORM_RETRIEVE. If it had been FORM_NEW it would have displayed default values instead of the retrieved record and saved the form as a new record in the table. 
} 

注意形式的管理()函數負責絕對一切的,從數據庫中檢索數據,呈現的形式進入視圖,驗證數據並將其保存回數據庫。

以編程方式創建表單(如上所述)的優點之一是可以編寫自己的基於表單的代碼生成器來創建用於生成表單的代碼。

我希望這可以幫助你或其他人。

+0

謝謝您的建議。我正在創建自己的Form Library,我從Laravel使用模式中獲得靈感。 – 2017-07-02 18:37:51