Zend Framework - Téléchargement de fichiers

Le téléchargement de fichiers est l'un des principaux concepts de la programmation de formulaires. Le framework Zend fournit tous les éléments nécessaires pour télécharger des fichiers via lezend-form et le zend-inputfilter composant.

Classe FileInput

Le composant zend-inputfilter fournit la classe Zend \ InputFilter \ FileInput pour gérer l'élément d'entrée du fichier html - <input type = 'file' />. leFileInputest comme les autres filtres d'entrée à quelques exceptions près. Ils sont les suivants -

  • Puisque PHP enregistre les détails du fichier téléchargé dans $_FILES tableau global, FileInput rassemble les informations sur le fichier téléchargé via $ _FILES uniquement.

  • La validation doit être effectuée avant que la classe FileInput ne traite les données. C'est le comportement opposé des autres filtres d'entrée.

  • Zend \ Validator \ File \ UploadFile est le validateur par défaut à utiliser. leUploadFile valide les détails d'entrée du fichier.

Pour ajouter un type de téléchargement de fichier dans un formulaire, nous devons utiliser le type d'entrée File. Le code partiel est le suivant -

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

Une autre classe utilisée dans le téléchargement de fichiers est Zend \ Filter \ File \ RenameUpload. leRenameUploadest utilisé pour déplacer le fichier téléchargé vers l'emplacement souhaité. La classe partielle pour utiliser le filtre de fichiers est la suivante -

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

Ici, les options de RenameUpload sont comme suit -

  • target - Le chemin de destination du fichier téléchargé.

  • randomize - Ajoutez une chaîne aléatoire pour éviter la duplication du fichier téléchargé.

  • use_upload_extension - Ajoutez l'extension de fichier au fichier téléchargé sur la cible.

Téléchargement de fichier - Exemple de travail

Modifions le module du didacticiel et incluons une fonction de téléchargement d'images.

Modifier la table de la base de données

Ajoutons le imagepath colonne à la table de livre en exécutant la commande SQL suivante -

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

Mettre à jour BookForm.php

Ajoutez l'élément d'entrée de fichier pour télécharger une image dans le formulaire de livre - myapp / module / Tutorial / src / Model / BookForm.php.

Incluez le code suivant dans le __constructmethod de la classe BookForm.

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

Mettre à jour Book.php

Effectuez les modifications suivantes dans la classe Book - myapp / module / Tutorial / src / Model / Book.php.

  • Ajouter une nouvelle propriété imagepath pour la photo.

public $imagepath;
  • Mettre à jour le getInputFilter méthode comme indiqué ci-dessous -

    • Ajouter le FileInput filtre pour l'élément d'entrée de fichier.

    • Met le UploadFile validation pour valider l'élément d'entrée du fichier.

    • Configurer le RenameUpload pour déplacer le fichier téléchargé vers la destination appropriée.

La liste partielle des codes est la suivante -

$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);
  • Mettre à jour le exchangeArray méthode pour inclure le imagepathpropriété. Le chemin de l'image peut provenir d'un formulaire ou d'une base de données. Si le chemin de l'image provient d'un formulaire, le format sera un tableau avec la spécification suivante -

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> 
   } 
}
  • Si le chemin d'image provient d'une base de données, ce sera une simple chaîne. La liste partielle du code pour analyser un chemin d'image est la suivante -

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

La liste complète des Book le modèle est le suivant -

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

Mettre à jour BookTable.php

Nous avons mis à jour BookForm et le Book model. Maintenant, nous mettons à jour leBookTable et modifier le saveBookméthode. Cela suffit pour inclure l'entrée imagepath dans le tableau de données,$data.

La liste partielle des codes est la suivante -

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

La liste complète des codes du BookTable la classe est la suivante -

<?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: Les informations de téléchargement de fichiers seront disponibles dans le $_FILES tableau global et il est accessible en utilisant le Request's getFiles()méthode. Alors, fusionnez les données publiées et les informations de téléchargement de fichiers comme indiqué ci-dessous.

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

La liste complète des addAction() la méthode est la suivante -

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

Mettre à jour la vue du fichier add.phtml

Enfin, modifiez le "add.phtml" et incluez l'élément d'entrée du fichier imagepath comme indiqué ci-dessous -

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

La liste complète est la suivante -

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

Lancez l'application

Enfin, exécutez l'application à l'adresse http://localhost:8080/tutorial/add et ajoutez les nouveaux enregistrements.

Le résultat sera comme indiqué dans les captures d'écran suivantes -

Form Page

Index Page