Zend Framework - Mengupload File

Pengunggahan file adalah salah satu konsep utama dalam pemrograman formulir. Zend framework menyediakan semua item yang diperlukan untuk mengupload file melaluizend-form dan zend-inputfilter komponen.

Kelas FileInput

Komponen zend-inputfilter menyediakan kelas Zend \ InputFilter \ FileInput untuk menangani elemen input file html - <input type = 'file' />. ItuFileInputseperti filter masukan lainnya dengan beberapa pengecualian. Mereka adalah sebagai berikut -

  • Karena PHP menyimpan detail file yang diunggah di $_FILES global array, FileInput mengumpulkan informasi file yang diunggah hanya melalui $ _FILES.

  • Validasi perlu dilakukan sebelum kelas FileInput memproses data. Ini adalah kebalikan dari perilaku filter masukan lainnya.

  • Zend \ Validator \ File \ UploadFile adalah validator default yang akan digunakan. ItuUploadFile memvalidasi detail input file.

Untuk menambahkan tipe unggahan file dalam formulir, kita perlu menggunakan tipe input File. Kode parsial adalah sebagai berikut -

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

Kelas lain yang digunakan dalam mengunggah file adalah Zend \ Filter \ File \ RenameUpload. ItuRenameUploaddigunakan untuk memindahkan file yang diunggah ke lokasi yang kami inginkan. Kelas parsial untuk menggunakan filter file adalah sebagai berikut -

$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);

Di sini, opsi RenameUpload adalah sebagai berikut -

  • target - Jalur tujuan dari file yang diunggah.

  • randomize - Tambahkan string acak untuk mencegah duplikasi file yang diunggah.

  • use_upload_extension - Tambahkan ekstensi file ke file yang diunggah ke target.

Unggah File - Contoh Kerja

Mari kita memodifikasi modul tutorial dan menyertakan fitur unggah gambar.

Ubah tabel database

Mari kita tambahkan imagepath kolom ke tabel buku dengan menjalankan perintah SQL berikut -

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

Perbarui BookForm.php

Tambahkan elemen input file untuk mengupload gambar dalam bentuk buku - myapp / module / Tutorial / src / Model / BookForm.php.

Sertakan kode berikut di __constructmethod dari kelas BookForm.

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

Perbarui Book.php

Lakukan perubahan berikut di kelas Buku - myapp / module / Tutorial / src / Model / Book.php.

  • Tambahkan properti baru imagepath untuk gambarnya.

public $imagepath;
  • Perbarui getInputFilter metode seperti yang ditunjukkan di bawah ini -

    • Tambahkan FileInput filter untuk elemen input file.

    • Mengatur UploadFile validasi untuk memvalidasi elemen input file.

    • Konfigurasikan RenameUpload untuk memindahkan file yang diunggah ke tujuan yang benar.

Daftar kode parsial adalah sebagai berikut -

$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);
  • Perbarui exchangeArray metode untuk memasukkan imagepathProperti. Jalur citra tersebut mungkin berasal dari formulir atau database. Jika imagepath berasal dari sebuah form, formatnya akan menjadi array dengan spesifikasi sebagai berikut:

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> 
   } 
}
  • Jika imagepath berasal dari database, itu akan menjadi string sederhana. Daftar kode parsial untuk mengurai sebuah jalur citra adalah sebagai berikut -

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; 
}

Daftar lengkap dari Book modelnya adalah sebagai berikut -

<?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; 
      } 
   } 
}

Perbarui BookTable.php

Kami telah memperbarui BookForm dan Book model. Sekarang, kami memperbaruiBookTable dan memodifikasi saveBookmetode. Ini cukup untuk memasukkan entri imagepath dalam larik data,$data.

Daftar kode parsial adalah sebagai berikut -

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

Daftar kode lengkap dari BookTable kelas adalah sebagai berikut -

<?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: Informasi unggahan file akan tersedia di $_FILES array global dan dapat diakses menggunakan Request's getFiles()metode. Jadi, gabungkan data yang diposting dan informasi unggahan file seperti yang ditunjukkan di bawah ini.

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

Daftar lengkap dari addAction() metode adalah sebagai berikut -

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); 
}

Perbarui View dari add.phtml

Terakhir, ubah "add.phtml" dan sertakan elemen input file imagepath seperti yang ditunjukkan di bawah ini -

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

Daftar lengkapnya adalah sebagai berikut -

<?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(); 
}

Jalankan aplikasinya

Terakhir, jalankan aplikasi di http://localhost:8080/tutorial/add dan tambahkan catatan baru.

Hasilnya akan seperti yang ditunjukkan pada tangkapan layar berikut -

Form Page

Index Page