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

form 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à:

  1. setData() để thiết lập biến cho form
  2. isValid() gọi các validator
  3. 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.

        

Đăng ký nhận bài viết mới