- Tạo form để Upload File với ZF3
- Đọc các file Upload
- Các Validator về File
- Các Filter về File
- Áp dụng Filter/Validator về File
Tạo Form để Upload File với ZF3
Trước tiên bạn nên đọc phần Upload File với PHP để hiểu quy trình gửi / nhận file với HTML và PHP.
Như bạn đã biết, để HTML FORM upload file thì form phải có phương thức post
và phải có thêm thuộc tính là enctype="multipart/form-data"
Giờ bạn sẽ mở ví dụ phần trước (Ví dụ ZEND FORM) để cập nhật thêm tính năng Upload File
Tạo action uploadfile vào controller Index như sau:
module/Application/src/Controller/IndexController.php
//... public function uploadfileAction() { //TẠO MODEL FORM TRỰC TIẾP $form = new Form('FileUpload'); $form->setAttribute('action', $this->url()->fromRoute('application', ['action'=>'uploadfile'])) ->setAttribute('method', 'post') ->setAttribute('class', 'p-4 bg-light') ->setAttribute('enctype', 'multipart/form-data') //Thêm phần tử File có tên fileupload ->add([ 'type' => 'File', 'name' => 'fileupload', //'options' => ['label' => 'Chọn file Upload'], 'attributes' => [ 'id' => 'fileupload', 'class' => 'form-control', 'value' => 'Upload File', 'multiple' => "multiple" ]]) ->add([ 'type' => 'submit', 'name' => 'submit', 'attributes' => [ 'class' => 'btn btn-warning', 'value' => 'Upload File', ], ]); return new ViewModel(['form' => $form]); } //...
Trong action trên bạn tạo ra một Model Form trực tiếp từ Zend\Form, có thuộc tính form enctype="multipart/form-data".
Trong FORM có phần tử tên fileupload
có kiểu File
là phần tử để chọn file Upload.
Bước tiếp theo bạn tạo ra template cho action này với nội dung như sau
module/Application/view/application/index/uploadfile.phtml
<h1>Ví dụ Upload File <small>ZF3</small></h1> <?php $form = $this->form; $form->prepare(); ?> <div class="col-md-6 mb-4"> <?= $this->form()->openTag($form); ?> <div class="form-group"> <?= $this->formRow($form->get('fileupload')); ?> </div> <?= $this->formElement($form->get('submit')); ?> <?= $this->form()->closeTag(); ?> </div>
Chạy thử với URL: http://localhost/zendform/application/uploadfile, kết quả là FORM cho phép chọn file Upload
Đọc các file upload
Như đã biết trong phần Upload File với PHP, các file Upload sẽ được PHP lưu giữ thông tin tại biến $_FILES
,
trong action của Controller bạn có thể dùng biến này như cách PHP thuần, tuy nhiên với ZF3 có thể lấy mảng chứa thông tin file bằng cách
$files = $this->params()->fromFiles(); //Hoặc $files = $this->getRequest()->getFiles(); //Hoặc lấy thẳng biến fileupload như tên trên form $file = $this->params()->fromFiles('fileupload');
Sau khi biết cách đọc biến file upload, bạn có thể xử lý như cách thông thường trong phần PHP cơ bản nếu muốn. Tuy nhiên, hãy sử dụng các chức năng của Filter / Validator về file một cách tốt hơn.
Validator về File
Để kiểm tra hợp lệ về file (kể cả file upload) có một số validator dùng sẵn như sau:
Extension | (Zend\Validator\File\Extension), các loại file cho phép 'options' => ['extension'=>['jpg','png',], 'case' => true] |
Count | (Zend\Validator\File\Count) giới hạn tổng số file upload 'options' => [ 'min' => 1, 'max' => 5, ] |
FilesSize | (Zend\Validator\File\FilesSize) kiểm tra cỡ file phù hợp 'options' => [ 'min' => '1kB', 'max' => '10MB', ] |
ImageSize | (Zend\Validator\File\ImageSize) kiểm tra cỡ ảnh 'options' => [ 'minWidth' => 320, 'minHeight' => 200, 'maxWidth' => 640, 'maxHeight' => 480,] |
IsImage | (Zend\Validator\File\IsImage) kiểm tra là ảnh |
IsCompressed | (Zend\Validator\File\IsCompressed) có phải file nén |
Filter về File
Các Filter tác động lên file upload
RenameUpload | (Zend\Filter\File\RenameUpload), đổi tên fileupload:
'options' => [ 'target' => null, //Thư mục 'use_upload_name' => false,//Sử dụng tên file gốc 'use_upload_extension' => false,//Sử dụng tên file gốc 'overwrite' => false, 'randomize' => false, ] |
Rename | (Zend\Filter\File\Rename), đổi tên file |
Áp dụng Filter/Validator với File
Khi áp dụng Filter/Validator để thực hiện với File Upload thì quy trình gọi thứ tự phương thức với $form đó là:
- setData() để thiết lập biến cho form
- isValid() gọi các validator
- getData() Khi isValid là true, gọi hàm này sẽ thi hành Filter
Cập nhật lại Action uploadfile ở trên bằng cách thêm InputFilter như sau:
module/Application/src/Controller/IndexController.php
//... public function uploadfileAction() { //TẠO MODEL FORM TRỰC TIẾP $form = new Form('FileUpload'); $form->setAttribute('action', $this->url()->fromRoute('application', ['action'=>'uploadfile'])) ->setAttribute('method', 'post') ->setAttribute('class', 'p-4 bg-light') ->setAttribute('enctype', 'multipart/form-data') //Thêm phần tử File có tên fileupload ->add([ 'type' => 'File', 'name' => 'fileupload', 'attributes' => [ 'id' => 'fileupload', 'class' => 'form-control', 'value' => 'Upload File', 'multiple'=> "multiple" ], 'options' => [ 'label' => 'Chọn file Upload', ], ]) ->add([ 'type' => 'submit', 'name' => 'submit', 'attributes' => [ 'class' => 'btn btn-warning', 'value' => 'Upload File', ], ]); $inputfilter = new \Zend\InputFilter\InputFilter(); //THÊM VALIDATOR VỀ FILE cho biến fileupload $inputfilter->add( [ 'name' => 'fileupload', 'validators' => [ [ 'name' => \Zend\Validator\File\Extension::class, 'options' => [ //Loại file được upload 'extension' => ['jpg','png','gif','jpeg'], 'case' => false //không phân biệt HOA/thường ] ], [ //Phải là file ảnh 'name' => \Zend\Validator\File\IsImage::class, ], ], ] ); //THÊM FILTER VỀ FILE cho biến fileupload $inputfilter->add( [ 'name' => 'fileupload', //Di chuyển file upload vào thư mục này 'filters' => [ [ 'name' => \Zend\Filter\File\RenameUpload::class, 'options' => [ 'target' => 'data/', //Thư mục 'use_upload_name' => true,//Sử dụng tên file gốc 'use_upload_extension' => true,//Sử dụng tên file gốc 'overwrite' => true, //'randomize' => true, ] ], ], ] ); $form->setInputFilter($inputfilter); $request = $this->getRequest(); if ($request->isPost()) { $form->setData(array_merge( $this->params()->fromPost(), $this->params()->fromFiles() )); if ($form->isValid()) { $data = $form->getData(); //var_dump($data); } } return new ViewModel(['form' => $form]); } //...
Với cách sửa code như trên bạn đã có thể upload các file ảnh vào thư mục data/
, nó sẽ chỉ cho phép upload các file có kiểu jpg, png, gif, jpeg
,
nó có kiểm tra xem có đúng là file ảnh không.