📅  最后修改于: 2020-10-16 07:43:16             🧑  作者: Mango
文件上传是表单编程中的主要概念之一。 Zend框架提供了通过zend-form和zend-inputfilter组件上传文件的所有必要项目。
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';
添加文件输入元素以书本形式上传图片-myapp / module / Tutorial / src / Model / BookForm.php。
在BookForm类的__construct方法中包含以下代码。
$this->add(array(
'name' => 'imagepath',
'type' => 'File',
'options' => array ('label' => 'Picture',),
));
在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;
}
}
}
我们更新了BookForm和Book模型。现在,我们更新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”并包含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运行该应用程序并添加新记录。
结果将如以下屏幕截图所示-
表格页
索引页