📜  Zend框架-文件上传

📅  最后修改于: 2020-10-16 07:43:16             🧑  作者: Mango


文件上传是表单编程中的主要概念之一。 Zend框架提供了通过zend-formzend-inputfilter组件上传文件的所有必要项目。

FileInput类别

zend-inputfilter组件提供Zend \ InputFilter \ FileInput类来处理html文件输入元素– FileInput与其他输入过滤器类似,但有一些例外。它们如下-

  • 由于PHP将上载的文件详细信息保存在$ _FILES全局数组中,因此FileInput仅通过$ _FILES收集上载的文件信息。

  • 在FileInput类处理数据之前,需要完成验证。这是其他输入过滤器的相反行为。

  • Zend \ Validator \ File \ UploadFile是要使用的默认验证器。 UploadFile验证文件输入详细信息。

要在表单中添加文件上传类型,我们需要使用输入类型File 。部分代码如下-

$form->add(array( 
   'name' => 'imagepath', 
   'type' => 'File', 
   'options' => array('label' => 'Picture',), 
)); 

文件上传中使用的另一个类是Zend \ Filter \ File \ RenameUpload。 RenameUpload用于将上传的文件移动到我们所需的位置。使用文件过滤器的部分类如下-

$file = new FileInput('imagepath'); 
$file->getValidatorChain()->attach(new UploadFile());
$file->getFilterChain()->attach( 
   new RenameUpload([ 
      'target'    => './public/tmpuploads/file', 
      'randomize' => true, 
      'use_upload_extension' => true 
   ]));
$inputFilter->add($file); 

在这里, RenameUpload的选项如下-

  • 目标-上传文件的目标路径。

  • 随机化-添加随机字符串以防止重复上传的文件。

  • use_upload_extension-将文件扩展名附加到上载的文件中。

文件上传–工作示例

让我们修改教程模块并包括图片上传功能。

修改数据库表

让我们通过执行以下SQL命令将imagepath列添加到book表:

ALTER TABLE `book` ADD `imagepath` VARCHAR(255) NOT NULL AFTER 'imagepath';

更新BookForm.php

添加文件输入元素以书本形式上传图片-myapp / module / Tutorial / src / Model / BookForm.php。

在BookForm类的__construct方法中包含以下代码。

$this->add(array( 
   'name' => 'imagepath', 
   'type' => 'File', 
   'options' => array ('label' => 'Picture',), 
)); 

更新Book.php

在Book类中进行以下更改– myapp / module / Tutorial / src / Model / Book.php。

  • 为图片添加新的属性imagepath

public $imagepath; 
  • 更新getInputFilter方法,如下所示-

    • 为文件输入元素添加FileInput过滤器。

    • 设置UploadFile验证以验证文件输入元素。

    • 配置RenameUpload以将上传的文件移动到正确的目的地。

部分代码清单如下-

$file = new FileInput('imagepath'); 
$file->getValidatorChain()->attach(new UploadFile()); 
$file->getFilterChain()->attach( 
   new RenameUpload([ 
      'target'    => './public/tmpuploads/file', 
      'randomize' => true, 'use_upload_extension' => true 
   ])); 
$inputFilter->add($file); 
  • 更新exchangeArray方法以包括imagepath属性。图像路径可能来自表单或数据库。如果imagepath来自表单,则格式将是具有以下规范的数组-

array(1) { 
   ["imagepath"] => array(5) { 
      ["name"]     => string "myimage.png" 
      ["type"]     => string "image/png"           
      ["tmp_name"] => string 
         "public/tmpuploads/file_." 
      ["error"]    => int  
      ["size"]     => int  
   } 
}
  • 如果imagepath来自数据库,它将是一个简单的字符串。解析图像路径的部分代码清单如下-

if(!empty($data['imagepath'])) { 
   if(is_array($data['imagepath'])) { 
      $this->imagepath = str_replace("./public", "", $data['imagepath']['tmp_name']); 
   } else { 
      $this->imagepath = $data['imagepath']; 
   } 
} else { 
   $data['imagepath'] = null; 
}

Book模型的完整清单如下-

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, 
                  ), 
               ), 
            ), 
         ));  
         $file = new FileInput('imagepath'); 
         $file->getValidatorChain()->attach(new UploadFile()); 
         $file->getFilterChain()->attach( 
            new RenameUpload([ 
               'target'    => './public/tmpuploads/file', 
               'randomize' => true, 
               'use_upload_extension' => true 
            ])); 
            $inputFilter->add($file);  
            $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; 
      
      if(!empty($data['imagepath'])) { 
         if(is_array($data['imagepath'])) { 
            $this->imagepath = str_replace("./public", "", 
               $data['imagepath']['tmp_name']); 
         } else { 
            $this->imagepath = $data['imagepath']; 
         } 
      } else { 
         $data['imagepath'] = null; 
      } 
   } 
}

更新BookTable.php

我们更新了BookFormBook模型。现在,我们更新BookTable并修改saveBook方法。这足以将imagepath条目包含在数据数组$ data中

部分代码清单如下-

$data = array('author' => $book->author, 'title'  => $book->title, 
   'imagepath' => $book->imagepath 
); 

BookTable类的完整代码清单如下:

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, 
         'imagepath' => $book->imagepath 
      );  
      $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'); 
         } 
      } 
   } 
}

更新TutorialController.php中的addAction :文件上载信息将在$ _FILES全局数组中提供,并且可以使用Request的getFiles()方法进行访问。因此,合并发布的数据和文件上传信息,如下所示。

$post = array_merge_recursive( 
   $request->getPost()->toArray(), 
   $request->getFiles()->toArray() 
); 

addAction()方法的完整清单如下:

public function addAction() { 
   $form = new BookForm(); 
   $form->get('submit')->setValue('Add');  
   $request = $this->getRequest(); 
   if ($request->isPost()) { 
      $book = new Book(); 
      $form->setInputFilter($book->getInputFilter()); 
      $post = array_merge_recursive( 
         $request->getPost()->toArray(), 
         $request->getFiles()->toArray() 
      );  
      $form->setData($post);   
      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); 
}

add.phtml的更新视图

最后,更改“ add.phtml”并包含imagepath文件输入元素,如下所示-

echo $this->formRow($form->get('imagepath'))."
";

完整的清单如下-

headTitle($title); 
?> 

escapeHtml($title); ?>

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'))."
"; echo $this->formRow($form->get('title'))."
"; echo $this->formRow($form->get('imagepath'))."
"; echo $this->formSubmit($form->get('submit')); echo $this->form()->closeTag(); }

运行应用程序

最后,在http:// localhost:8080 / tutorial / add运行该应用程序并添加新记录。

结果将如以下屏幕截图所示-

表格页

新书范例

索引页

索引页