Zend Framework - Caricamento di file
Il caricamento dei file è uno dei concetti principali nella programmazione dei moduli. Il framework Zend fornisce tutti gli elementi necessari per caricare i file tramitezend-form e il zend-inputfilter componente.
Classe FileInput
Il componente zend-inputfilter fornisce la classe Zend \ InputFilter \ FileInput per gestire l'elemento di input del file html - <input type = 'file' />. IlFileInputè come gli altri filtri di input con poche eccezioni. Sono i seguenti:
Poiché PHP salva i dettagli del file caricato in formato $_FILES array globale, FileInput raccoglie le informazioni sul file caricato solo tramite $ _FILES.
La convalida deve essere eseguita prima che la classe FileInput elabori i dati. È il comportamento opposto degli altri filtri di input.
Zend \ Validator \ File \ UploadFile è il validatore predefinito da utilizzare. IlUploadFile convalida i dettagli di input del file.
Per aggiungere un tipo di caricamento file in un modulo, è necessario utilizzare il tipo di input File. Il codice parziale è il seguente:
$form->add(array(
'name' => 'imagepath',
'type' => 'File',
'options' => array('label' => 'Picture',),
));
Un'altra classe utilizzata nel caricamento dei file è Zend \ Filter \ File \ RenameUpload. IlRenameUploadviene utilizzato per spostare il file caricato nella posizione desiderata. La classe parziale per utilizzare il filtro file è la seguente:
$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);
Qui, le opzioni di RenameUpload sono i seguenti -
target - Il percorso di destinazione del file caricato.
randomize - Aggiungi una stringa casuale per evitare la duplicazione del file caricato.
use_upload_extension - Aggiungi l'estensione del file al file caricato alla destinazione.
Caricamento di file - Esempio di lavoro
Modifichiamo il modulo del tutorial e includiamo una funzione di caricamento delle immagini.
Modifica la tabella del database
Aggiungiamo il file imagepath colonna alla tabella del libro eseguendo il seguente comando SQL:
ALTER TABLE `book` ADD `imagepath` VARCHAR(255) NOT NULL AFTER 'imagepath';
Aggiorna BookForm.php
Aggiungi l'elemento di input del file per caricare un'immagine nel formato del libro: myapp / module / Tutorial / src / Model / BookForm.php.
Includere il codice seguente nel file __constructmethod della classe BookForm.
$this->add(array(
'name' => 'imagepath',
'type' => 'File',
'options' => array ('label' => 'Picture',),
));
Aggiorna Book.php
Esegui le seguenti modifiche nella classe Book: myapp / module / Tutorial / src / Model / Book.php.
Aggiungi una nuova proprietà imagepath per l'immagine.
public $imagepath;
Aggiorna il file getInputFilter metodo come mostrato di seguito -
Aggiungi il FileInput filtro per elemento di input del file.
Impostare il UploadFile convalida per convalidare l'elemento di input del file.
Configura il RenameUpload per spostare il file caricato nella destinazione corretta.
L'elenco dei codici parziale è il seguente:
$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);
Aggiorna il file exchangeArray metodo per includere il imagepathproprietà. Il percorso dell'immagine può provenire da un modulo o da un database. Se il percorso dell'immagine proviene da un modulo, il formato sarà un array con la seguente specifica:
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>
}
}
Se il percorso dell'immagine proviene da un database, sarà una semplice stringa. L'elenco di codice parziale per analizzare un percorso immagine è il seguente:
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;
}
L'elenco completo di Book il modello è il seguente:
<?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;
}
}
}
Aggiorna BookTable.php
Abbiamo aggiornato BookForm e il Book model. Ora aggiorniamo il fileBookTable e modificare il file saveBookmetodo. Questo è sufficiente per includere la voce del percorso immagine nell'array di dati,$data.
L'elenco dei codici parziale è il seguente:
$data = array('author' => $book->author, 'title' => $book->title,
'imagepath' => $book->imagepath
);
L'elenco completo del codice di BookTable la classe è la seguente:
<?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: Le informazioni sul caricamento dei file saranno disponibili nel file $_FILES array globale ed è possibile accedervi utilizzando il Request's getFiles()metodo. Quindi, unisci i dati pubblicati e le informazioni di caricamento dei file come mostrato di seguito.
$post = array_merge_recursive(
$request->getPost()->toArray(), $request->getFiles()->toArray()
);
L'elenco completo di addAction() metodo è il seguente:
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);
}
Aggiorna la vista del file add.phtml
Infine, cambia "add.phtml" e includi l'elemento di input del file imagepath come mostrato di seguito -
echo $this->formRow($form->get('imagepath'))."<br>";
L'elenco completo è il seguente:
<?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();
}
Esegui l'applicazione
Infine, esegui l'applicazione su http://localhost:8080/tutorial/add e aggiungi i nuovi record.
Il risultato sarà come mostrato negli screenshot seguenti:
Form Page
Index Page