Zend Framework - การอัปโหลดไฟล์
การอัปโหลดไฟล์เป็นหนึ่งในแนวคิดหลักในการเขียนโปรแกรมแบบฟอร์ม Zend framework ให้รายการที่จำเป็นทั้งหมดในการอัปโหลดไฟล์ผ่านไฟล์zend-form และ zend-inputfilter ส่วนประกอบ.
คลาส FileInput
คอมโพเนนต์ zend-inputfilter จัดเตรียมคลาส Zend \ InputFilter \ FileInput เพื่อจัดการองค์ประกอบอินพุตไฟล์ html - <input type = 'file' />. 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 มีดังนี้ -
target - เส้นทางปลายทางของไฟล์ที่อัปโหลด
randomize - เพิ่มสตริงแบบสุ่มเพื่อป้องกันการทำซ้ำไฟล์ที่อัปโหลด
use_upload_extension - ต่อท้ายนามสกุลไฟล์กับไฟล์ที่อัพโหลดไปยังเป้าหมาย
อัปโหลดไฟล์ - ตัวอย่างการทำงาน
ให้เราแก้ไขโมดูลการสอนและรวมคุณสมบัติการอัปโหลดรูปภาพ
ปรับเปลี่ยนตารางฐานข้อมูล
ให้เราเพิ่มไฟล์ imagepath คอลัมน์ไปยังตารางหนังสือโดยดำเนินการคำสั่ง SQL ต่อไปนี้ -
ALTER TABLE `book` ADD `imagepath` VARCHAR(255) NOT NULL AFTER 'imagepath';
อัพเดท BookForm.php
เพิ่มองค์ประกอบการป้อนไฟล์เพื่ออัปโหลดรูปภาพในรูปแบบหนังสือ - myapp / module / Tutorial / src / Model / BookForm.php
รวมรหัสต่อไปนี้ในไฟล์ __constructmethod ของคลาส BookForm
$this->add(array(
'name' => 'imagepath',
'type' => 'File',
'options' => array ('label' => 'Picture',),
));
อัพเดท Book.php
ทำการเปลี่ยนแปลงต่อไปนี้ในคลาสหนังสือ - 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ทรัพย์สิน. อิมเมจพา ธ อาจมาจากฟอร์มหรือฐานข้อมูล หากอิมเมจพา ธ มาจากฟอร์มรูปแบบจะเป็นอาร์เรย์ที่มีข้อกำหนดดังต่อไปนี้ -
array(1) {
["imagepath"] => array(5) {
["name"] => string "myimage.png"
["type"] => string "image/png"
["tmp_name"] => string
"public/tmpuploads/file_<random_string>.<image_ext>"
["error"] => int <error_number>
["size"] => int <size>
}
}
ถ้าอิมเมจพา ธ มาจากฐานข้อมูลก็จะเป็นสตริงธรรมดา รายการรหัสบางส่วนเพื่อแยกวิเคราะห์ 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 โมเดลมีดังนี้ -
<?php
namespace Tutorial\Model;
use Zend\InputFilter\InputFilterInterface;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\Filter\File\RenameUpload;
use Zend\Validator\File\UploadFile;
use Zend\InputFilter\FileInput;
use Zend\InputFilter\InputFilter;
class Book implements InputFilterAwareInterface {
public $id; public $author;
public $title; public $imagepath;
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, ), ), ), )); $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
เราอัปเดตแล้ว BookForm และ Book model. ตอนนี้เราอัปเดตไฟล์BookTable และแก้ไขไฟล์ saveBookวิธี. นี่เพียงพอที่จะรวมรายการอิมเมจพา ธ ในอาร์เรย์ข้อมูล$data.
รายการรหัสบางส่วนมีดังนี้ -
$data = array('author' => $book->author, 'title' => $book->title,
'imagepath' => $book->imagepath
);
รายการรหัสที่สมบูรณ์ของไฟล์ BookTable คลาสมีดังนี้ -
<?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, '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');
}
}
}
}
Update addAction in the TutorialController.php: ข้อมูลการอัปโหลดไฟล์จะอยู่ในไฟล์ $_FILES global array และสามารถเข้าถึงได้โดยใช้ Request's 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'))."<br>";
รายชื่อที่สมบูรณ์มีดังนี้ -
<?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->formRow($form->get('imagepath'))."<br>"; echo $this->formSubmit($form->get('submit')); echo $this->form()->closeTag();
}
เรียกใช้แอปพลิเคชัน
สุดท้ายเรียกใช้แอปพลิเคชันที่ http://localhost:8080/tutorial/add และเพิ่มระเบียนใหม่
ผลลัพธ์จะเป็นดังที่แสดงในภาพหน้าจอต่อไปนี้ -
Form Page
Index Page