Zend Framework - 表單與驗證



Zend Framework 提供了一個單獨的元件,zend-form,用於加速表單建立和驗證過程。它連線了模型和檢視層。它提供了一組表單元素,可以從預定義的模型建立完整的 html 表單,一個InputFilter類用於根據表單驗證模型,以及將表單中的資料繫結到模型並反之亦然的功能。

安裝表單元件

Zend 表單元件可以使用如下所示的Composer命令安裝:

composer require zendframework/zend-form 

Zend 表單框架有三個子元件來管理表單。它們如下詳細解釋:

  • 元素 - 用於定義對映到模型中屬性的單個 html 輸入控制元件。

  • 欄位集 - 用於以巢狀方式對元素和其他欄位集進行分組。

  • 表單 - 用於建立 html 表單,幷包含元素和欄位集。

Zend 表單通常在module//src/Form目錄下建立。

示例

現在讓我們建立一個簡單的表單,將圖書新增到資料庫中。為此,我們應該遵循以下步驟:

步驟 1:建立 BookForm

在*myapp/module/Tutorial/src/Form”目錄下建立“BookForm.php”。在檔案中新增以下更改:

<?php  
namespace Tutorial\Form;  
use Zend\Form\Form;  

class BookForm extends Form {
   
   public function __construct($name = null) { 
      parent::__construct('book');  
      $this->add(array( 
         'name' => 'id', 
         'type' => 'Hidden', 
      ));  
      $this->add(array( 
         'name' => 'author', 
         'type' => 'Text', 
         'options' => array( 
            'label' => 'Author', 
         ), 
      ));  
      $this->add(array( 
         'name' => 'title', 
         'type' => 'Text', 
         'options' => array( 
            'label' => 'Title', 
         ), 
      ));  
      $this->add(array( 
         'name' => 'submit', 
         'type' => 'Submit', 
         'attributes' => array( 
            'value' => 'Go', 
            'id' => 'submitbutton', 
         ), 
      )); 
   } 
}

Form類提供了一個add 方法來對映模型及其對應的表單細節。我們透過擴充套件Form類建立了BookForm,並添加了Book模型的表單細節。

步驟 2:更新圖書模型,Book.php

更新模型‘Book’,新增如下所示的過濾器和驗證:

<?php 
namespace Tutorial\Model;  
use Zend\InputFilter\InputFilterInterface; 
use Zend\InputFilter\InputFilterAwareInterface; 
use Zend\InputFilter\InputFilter;  

class Book implements InputFilterAwareInterface { 
   public $id; 
   public $author; 
   public $title;  
   protected $inputFilter;  
   public function setInputFilter(InputFilterInterface $inputFilter) { 
      throw new \Exception("Not used"); 
   }  
   public function getInputFilter() { 
      if (!$this->inputFilter) { 
         $inputFilter = new InputFilter(); 
         $inputFilter->add(array( 
            'name' => 'id', 
            'required' => true, 
            'filters' => array( 
               array('name' => 'Int'), 
            ),
         )); 
         $inputFilter->add(array( 
            'name' => 'author', 
            'required' => true, 
            'filters' => array( 
               array('name' => 'StripTags'), 
               array('name' => 'StringTrim'), 
            ), 
            'validators' => array( 
               array( 
                  'name' => 'StringLength', 
                  'options' => array( 
                     'encoding' => 'UTF-8', 
                     'min' => 1, 
                     'max' => 100, 
                  ), 
               ), 
            ), 
         )); 
         $inputFilter->add(array( 
            'name' => 'title', 
            'required' => true, 
            'filters' => array( 
               array('name' => 'StripTags'), 
               array('name' => 'StringTrim'), 
            ), 
            'validators' => array( 
               array( 
                  'name' => 'StringLength', 
                  'options' => array( 
                     'encoding' => 'UTF-8', 
                     'min' => 1, 
                     'max' => 100, 
                  ), 
               ),
            ),  
         )); 
         $this->inputFilter = $inputFilter; 
      } 
      return $this->inputFilter; 
   }  
   public function exchangeArray($data) { 
      $this->id = (!empty($data['id'])) ? $data['id'] : null; 
      $this->author = (!empty($data['author'])) ? $data['author'] : null; 
      $this->title = (!empty($data['title'])) ? $data['title'] : null; 
   } 
}

每個模型都應該實現InputFilterAwareInterface。InputFilterAwareInterface 提供了兩種方法,setInputFilter()getInputFilter()

getInputFilter 用於獲取模型的驗證細節。Zend 框架提供了一套豐富的過濾器和驗證器來驗證表單。在圖書模型中使用的一些過濾器和驗證器如下所示:

  • StripTags - 刪除不需要的 HTML。

  • StringTrim - 刪除不必要的空格。

  • StringLength 驗證器 - 確保使用者輸入的字元數不超過指定限制。

步驟 3:更新 BookTable 類

包含saveBook方法以將圖書新增到資料庫。

BookTable.php

<?php  
namespace Tutorial\Model;  
use Zend\Db\TableGateway\TableGatewayInterface;  

class BookTable {
   protected $tableGateway; 
   public function __construct(TableGatewayInterface $tableGateway) { 
      $this->tableGateway = $tableGateway; 
   }  
   public function fetchAll() { 
      $resultSet = $this->tableGateway->select(); 
      return $resultSet; 
   }  
   public function getBook($id) { 
      $id  = (int) $id; 
      $rowset = $this->tableGateway->select(array('id' => $id)); 
      $row = $rowset->current(); 
      if (!$row) { 
         throw new \Exception("Could not find row $id"); 
      } 
      return $row; 
   }  
   public function saveBook(Book $book) { 
      $data = array ( 
         'author' => $book->author, 
         'title'  => $book->title, 
      );  
      $id = (int) $book->id; 
      if ($id == 0) { 
         $this->tableGateway->insert($data); 
      } else {
         if ($this->getBook($id)) { 
            $this->tableGateway->update($data, array('id' => $id));  
         } else { 
            throw new \Exception('Book id does not exist'); 
         } 
      } 
   } 
}

步驟 4:更新 TutorialController 類

在教程控制器中新增一個新的操作 addAction – myapp/module/Tutorial/src/Controller/TutorialController.php。

public function addAction() { 
   $form = new BookForm(); 
   $form->get('submit')->setValue('Add');  
   $request = $this->getRequest(); 
   if ($request->isPost()) { 
      $book = new Book(); 
      $form->setInputFilter($book->getInputFilter()); 
      $form->setData($request->getPost());  
      if ($form->isValid()) { 
         $book->exchangeArray($form->getData()); 
         $this->bookTable->saveBook($book);  
         
         // Redirect to list of Tutorial 
         return $this->redirect()->toRoute('tutorial'); 
      } 
   }  
   return array('form' => $form); 
}

addAction方法執行以下過程:

  • 獲取請求物件。

  • 檢查請求的 http 方法是否為post方法。

  • 如果請求的 http 方法不是post,則只渲染模板add.phtml

  • 如果請求的 http 方法不是post,則設定inputfilter,獲取請求資料並將其設定到 inputfiler 中。

  • 使用 Form 類的isValid()方法檢查表單是否有效。

  • 如果表單無效,則再次渲染模板add.phtml

  • 如果表單有效,則將圖書儲存到資料庫中,並重定向到主頁。

步驟 5:新增 add.phtml 模板

在 myapp/module/Tutorial/view/tutorial/tutorial/add.phtml 下建立一個模板 – add.phtml

Add.phtml

<?php  
$title = 'Add new Book'; 
$this->headTitle($title);  
?>  
<h1><?php echo $this->escapeHtml($title); ?></h1>  
<?php  
if(!empty($form)) {  
   $form->setAttribute('action', $this->url('tutorial', array('action' => 'add'))); 
   $form->prepare();  
   echo $this->form()->openTag($form); 
   echo $this->formHidden($form->get('id')); 
   echo $this->formRow($form->get('author'))."<br>"; 
   echo $this->formRow($form->get('title'))."<br>"; 
   echo $this->formSubmit($form->get('submit')); 
   echo $this->form()->closeTag(); 
} 

這裡,我們使用Form例項$form渲染圖書表單。

步驟 6:執行應用程式

現在,我們可以執行應用程式 – https://:8080/tutorial/add

表單頁面

Form Page

驗證錯誤頁面

Error Page
廣告