【问题标题】:Inputfilter for fileupload, basic usage文件上传的输入过滤器,基本用法
【发布时间】:2017-07-10 18:05:21
【问题描述】:

现在我对 ZF3 的东西更感兴趣了。我可以(在一些帮助下)实现我想要的几乎所有东西。为了深入了解新版本,我开发了一个测试项目。

有些问题仍然没有答案,我没有找到有用的解释。

我的新问题是InputFilterAwareInterface。我尝试了教程中的字符串示例,到目前为止一切正常。但是像往常一样,对于简单的主题,你会发现一切,如果你走得更远,它就会突然结束。

我需要一个用于 xls 和 xlsx 文件的 Inputfilter。当然,我用谷歌搜索,阅读教程,在 zend 教程中搜索,因为我认为某处必须存在一些完整的参考,但我找不到任何。

所以我尝试了这个:

    $inputFilter->add([
                'type'     => 'Zend\InputFilter\FileInput',
                'name'     => 'DCL_Path',
                'required' => true,
                'validators' => [
                        ['name'    => 'FileUploadFile'],
                        [
                                'name'    => 'FileMimeType',
                                'options' => [
                                        'mimeType'  => ['text/xls', 'text/xlsx']
                                ]
                        ],
                        [
                                'name'    => 'Filesize',
                                'options' => [
                                        'max' => 4096
                                ]
                        ],
                ],
//              'filters'  => [
//                      [
//                              'name' => 'FileRenameUpload',
//                              'options' => [
//                                      'target'=>'./data/upload',
//                                      'useUploadName'=>true,
//                                      'useUploadExtension'=>true,
//                                      'overwrite'=>true,
//                                      'randomize'=>false
//                              ]
//                      ]
//              ],
        ]); 

如您所见,我仍在与验证者部分作斗争。验证最大大小为 4 MB 的 xls 和 xlsx 文件的正确语法是什么?

然后,过滤区域呢,我在控制器操作中做了以下操作,只是因为我习惯了

if ($form->isValid()) {
                    $data = $form->getData();
                    // Upload path
                    $location = "public/files/";
                    // A bit validation of uploaded file
                    $allowedExtension = array('xls', 'xlsx');
                    $extension = explode('.', $data['DCL_Path']['name']);
                    $extension = end($extension);
                    //$import['DCL_Path']=$data['DCL_Path']['name'];
                    //$fileName = time() . '.' . $extension;
                    $fileName = $data['DCL_Path']['name'];
                    // Check if everything is OK!
                    //echo $fileName;
                    if (0 === $data['DCL_Path']['error'] && in_array($extension, $allowedExtension)) {
                        move_uploaded_file($data['DCL_Path']['tmp_name'], $location . $fileName);
                    } else {
                        echo 'Something went wrong!';
                    }

move_uploaded_file($data['DCL_Path']['tmp_name'], $location . $fileName); 界面中的过滤器是否已过时?在这种情况下,语法又会如何?

我最大的愿望之一是,有人知道一种教程,它清楚地解释了两个选项(验证器和过滤器)的不同可能性和键吗?有时我无法相信你需要这么多时间才能找到正确的钥匙。

编辑 1:显示表单、过滤器和更改的控制器

这是我的 Form 类的一部分:

<?php
namespace Import\Form;

use Zend\Form\Form;
class ImportForm extends Form
{
    public function __construct($name = null)
    {
        // We will ignore the name provided to the constructor
        parent::__construct('import');

        $this->add([
                'name' => 'DCLID',
                'type' => 'hidden',
        ]);
        $this->add([
                'name' => 'UnitID',
                'type' => 'text',
                'options' => [
                        'label' => 'equipment',

                ],
        ]);
        $this->add([
                'name' => 'DCL_Path',
                'type' => 'File',
                //'required' => true,
                'options' => [
                        'label' => 'path to file',

                ],
                //              'name' => 'FileRenameUpload',
//              'filters' => [
//                      'target'=>'./public/files',
//                      'useUploadName'=>true,
//                      'useUploadExtension'=>true,
//                      'overwrite'=>true,
//                      'randomize'=>false
//                  ],
//              'validators' => [      // Validators.
//                      // Put validator info here.
//              ]
        ]);

这里部分类扩展InputFilterAwareInterface

<?php
namespace Import\Model;
use DomainException;
use Zend\Filter\StringTrim;
use Zend\Filter\StripTags;
use Zend\Filter\ToInt;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;
use Zend\Validator\StringLength;

class Import implements InputFilterAwareInterface
{
    public $DCLID;
    public $DCL_Path;
    public $Unitname;
    public $UnitID;
    public $Importdate;
    public $Importuser;
    public $Importok;
    public $DCL_Type;
    public $Changed_per_User;
    public $Description_Changes;

    private $inputFilter;

    public function exchangeArray(array $data)
    {
        $this->DCLID= !empty($data['DCLID']) ? $data['DCLID'] : null;
        $this->UnitID= !empty($data['UnitID']) ? $data['UnitID'] : null;
        $this->DCL_Path= !empty($data['DCL_Path']) ? $data['DCL_Path'] : null;
        $this->Importdate= !empty($data['Importdate']) ? $data['Importdate'] : null;
        $this->Importuser= !empty($data['Importuser']) ? $data['Importuser'] : null;
        $this->Importok= !empty($data['Importok']) ? $data['Importok'] : null;
        $this->DCL_Type= !empty($data['DCL_Type']) ? $data['DCL_Type'] : null;
        $this->Changed_per_User= !empty($data['Changed_per_User']) ? $data['Changed_per_User'] : null;
        $this->Description_Changes= !empty($data['Description_Changes']) ? $data['Description_Changes'] : null;
    }

    public function getArrayCopy()
    {
        //      echo var_dump(get_object_vars($this)
        //              );

        return get_object_vars($this);
    }

    public function setInputFilter(InputFilterInterface $inputFilter)
    {
        throw new DomainException(sprintf(
                '%s does not allow injection of an alternate input filter',
                __CLASS__
                ));
    }

    public function getInputFilter()
    {
        if ($this->inputFilter) {
            return $this->inputFilter;
        }

        $inputFilter = new InputFilter();

//      $inputFilter->add([
//              'name' => 'DCLID',
//              'required' => false,
//              'filters' => [
//                      ['name' => ToInt::class],
//              ],
//      ]);
        // Validator für das Upload Element

        $inputFilter->add([
                'type'     => 'Zend\InputFilter\FileInput',
                'name'     => 'DCL_Path',  // Element's name.
                'required' => true,    // Whether the field is required.
                'filters'  => [        // Filters.
                        [
                                'name' => \Zend\Filter\File\RenameUpload::class,
                                'options' => [
                                        'use_upload_extension' => true,
                                        'randomize' => false,
                                        'overwrite' => true,
                                        'target' => 'public/files',
                                ],
                        ],
                ],
                'validators' => [      // Validators.
                        [
                                'name' => \Zend\Validator\File\Extension::class,
                                'options' => [
                                        'extension' => 'xls, xlsx',
                                        'message' => 'File extension not match',
                                ],
                        ],
                        [
                                'name' => \Zend\Validator\File\MimeType::class,
                                'options' => [
                                        'mimeType' => 'text/xls', 'text/xlsx',
                                        'message' => 'File type not match',
                                ],
                        ],
                        [
                                'name' => \Zend\Validator\File\Size::class,
                                'options' => [
                                        'min' => '1kB',  // minimum of 1kB
                                        'max' => '4MB',
                                        'message' => 'File too large',
                                ],
                        ],
                ]
        ]);

和我的部分控制器动作,我认为这可能是问题所在,可能不是逻辑:

$form = new ImportForm();
        $form->get('submit')->setValue('Add');  //Änderung des LAbels des Submit Buttons, um das Form wiederverwenden zu können
        //echo "hier";
        $request = $this->getRequest();
        if (! $request->isPost()) {     //wurden  Daten über POST geschickt?
            return ['form' => $form];   //Keine Daten, nur Form anzeigen, nicht verarbeiten
        }   
        else {
        //Es wurden Daten gesendet
            //echo "Daten";
            $import = new Import();     //Neue Instanz von Import
            $form->setInputFilter($import->getInputFilter());       //Filter an Form binden
            $form->setData($request->getPost());        //Daten abholen
            //echo $form->isValid();
            if (! $form->isValid()) {
                return ['form' => $form];       //Wenn die Daten nicht valide sind
            }   
            else{           //aus Tableadapter
                    $import->exchangeArray($form->getData());
                    $data = array_merge_recursive(
                            $this->getRequest()->getPost()->toArray(),
                            $this->getRequest()->getFiles()->toArray()
                            );
                    $form->setData($data);
                    if ($form->isValid()) {
                        $data = $form->getData();
                        // Upload path
                //      $location = "public/files/";
//                      $allowedExtension = array('xls', 'xlsx');
//                      $extension = explode('.', $data['DCL_Path']['name']);
//                      $extension = end($extension);
                        $fileName = $data['DCL_Path']['name'];
//                      // Check if everything is OK!
//                      //echo $fileName;
//                      if (0 === $data['DCL_Path']['error'] && in_array($extension, $allowedExtension)) {
//                          move_uploaded_file($data['DCL_Path']['tmp_name'], $location . $fileName);
//                      } else {
//                          echo 'Something went wrong!';
//                      }

                        //-----------------------------------------------------------------
                        // t_dcl befüllen
                        //-----------------------------------------------------------------
                        //$namen = explode(",", $import ); //Konvertierung des Strings in ein Array
                        //echo "<pre>"; var_dump($namen); echo "</pre>"; //Formartierte Ausgabe des Arrays
                        $this->table->saveImport($import);  

EDIT2:发布部分控制器操作以讨论某些语句的顺序:

控制器动作

$form = new ImportForm();
        $form->get('submit')->setValue('Add');  
        $request = $this->getRequest();
        if (! $request->isPost()) {     
            return ['form' => $form];   
        }   
        else {
            $import = new Import();     //Neue Instanz von Import
            $form->setInputFilter($import->getInputFilter());       
            $form->setData($request->getPost());        
            $data = array_merge_recursive(
                    $this->getRequest()->getPost()->toArray(),
                    $this->getRequest()->getFiles()->toArray()
                    );
            $form->setData($data);
            if (! $form->isValid()) {
                return ['form' => $form];       
            }   
            else{           
                    $import->exchangeArray($form->getData());
                    $data = $form->getData();
                    $fileName = $data['DCL_Path']['name'];

$form-&gt;setInputFilter($import-&gt;getInputFilter());的位置对吗?或者我什么时候必须将 Inputfilter 绑定到表单?

还有一个小问题:我现在有一个消息:

文件类型不匹配

我尝试上传一个 .xlsx 文件

【问题讨论】:

    标签: validation zend-framework zend-framework3


    【解决方案1】:

    请为InputFilter试试这个

            $inputFilter->add([
                'type'     => 'Zend\InputFilter\FileInput',
                'name'     => 'DCL_Path',  // Element's name.
                'required' => true,    // Whether the field is required.
                'filters'  => [        // Filters.
                    [
                        'name' => \Zend\Filter\File\RenameUpload::class,
                        'options' => [
                            'use_upload_extension' => true,
                            'randomize' => false,
                            'overwrite' => true,
                            'target' => 'public/files',
                        ],
                    ],
                ],
                'validators' => [      // Validators.
                    [
                        'name' => \Zend\Validator\File\Extension::class,
                        'options' => [
                            'extension' => 'xls, xlsx',
                            'message' => 'File extension not match',
                        ],
                    ],
                    [
                        'name' => \Zend\Validator\File\MimeType::class,
                        'options' => [
                            'mimeType' => 'text/xls', 'text/xlsx',
                            'message' => 'File type not match',
                        ],
                    ],
                    [
                        'name' => \Zend\Validator\File\Size::class,
                        'options' => [
                            'max' => '4MB',
                            'message' => 'File too large',
                        ],
                    ],
                ]
            ]);
    

    这里是控制器

        if($this->getRequest()->isPost()) {
            // merge post and files
            $request = $this->getRequest();
            $data = array_merge_recursive(
                $request->getPost()->toArray(),
                $request->getFiles()->toArray()
            );
    
            // passing data
            $form->setData($data);
    
            // execute validator
            if($form->isValid()) {
                // execute file filters.
                $data = $form->getData();
            }
        }
    

    通过使用\Zend\Validator\File\Extension\Zend\Validator\File\MimeType\Zend\Validator\File\FileSize,您无需使用此代码在您的控制器中手动检查。

    if (0 === $data['DCL_Path']['error'] && in_array($extension, $allowedExtension)) {}
    

    因为当我们调用$form-&gt;isValid()时会执行验证。

    通过使用\Zend\Filter\File\RenameUpload,您不再需要使用move_uploaded_file()。因为此过滤器会将上传的文件移动到我们在'target' =&gt; 'public/files' 选项中定义的目标目录。

    当我们调用$form-&gt;getData();时执行过滤

    关于ValidatorFilter的解释,我建议你再发一个帖子。通过使用单独的问题,可以很容易地在搜索引擎中搜索并帮助其他人找到它。

    【讨论】:

    • 首先:您的帖子真的很有帮助,我了解何时执行验证以及何时过滤器开始工作,并且我的建议是正确的,在它被重复之前。其次,我收到一个错误,可能可以快速修复:在插件管理器 Zend\Validator\ValidatorPluginManager 中找不到名为“Zend\Validator\File\FileSize”的插件我必须通过 composer 获取它吗?跨度>
    • 好的,应该是 \Zend\Validator\File\FilesSize 但是现在我有一个额外的问题,我选择了一个文件,提交后我收到了这个验证消息:“值是必需的,不能是空”
    • 抱歉,使用\Zend\Validator\File\Size 代替`Zend\Validator\File\FileSize`
    • 同样的错误“需要值..”必须接近解决方案
    • 请检查Form,您是否使用DCL_Path 作为input file 名称?
    猜你喜欢
    • 2016-11-28
    • 1970-01-01
    • 2015-07-01
    • 1970-01-01
    • 2012-08-22
    • 1970-01-01
    • 2013-03-22
    • 2022-08-23
    • 1970-01-01
    相关资源
    最近更新 更多