Zend Framework - 表单和验证

  • 简述

    Zend Framework 提供了一个单独的组件,zend-form来加速表单创建和验证过程。它连接模型和视图层。它提供了一组表单元素,用于从预定义的模型创建完整的 html 表单,InputFilter 类用于根据表单验证模型,以及用于将数据从表单绑定到模型的选项,反之亦然。
  • 安装表单组件

    Zend 表单组件可以使用下面指定的 Composer 命令进行安装 −
    
    composer require zendframework/zend-form 
    
    Zend 表单框架有三个子组件来管理表单。它们如下所述 -
    • Elements − 用于定义映射到模型中的属性的单个 html 输入控件。
    • Fieldset − 用于以嵌套方式对元素和其他Fieldset进行分组。
    • Form − 用于创建 html 表单,由元素和字段集组成。
    Zend 表单通常在module/src/Form目录下创建。
  • 现在让我们创建一个简单的表单,将book添加到数据库中。为此,我们应该遵循以下步骤 -

    步骤 1:创建book表单

    在 “*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模型,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 框架提供了一组丰富的过滤器和验证器来验证表单。 book 模型中使用的一些过滤器和验证器如下 -
    • 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”类

    在教程控制器中添加一个新的操作添加操作 – 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,获取请求数据并将其设置为输入文件管理器。
    • 使用 Form 类的 isValid() 方法检查表单是否有效。
    • 如果表单无效,它将再次呈现模板 add.phtml
    • 如果表单有效,它会将书籍保存到数据库中并重定向到主页。

    步骤 5:添加 add.phtml 模板

    创建一个模板 – 在 myapp/module/Tutorial/view/tutorial/tutorial/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:运行应用程序

    现在,我们可以运行应用程序 - http://localhost:8080/tutorial/add
    表单页面
    表单页面
    “验证错误”页
    错误页面