Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 文件上传不';无法创建上载的文件_Php_Forms_Symfony_Symfony 2.4 - Fatal编程技术网

Php 文件上传不';无法创建上载的文件

Php 文件上传不';无法创建上载的文件,php,forms,symfony,symfony-2.4,Php,Forms,Symfony,Symfony 2.4,我目前正在从事一个PHP v5.5.9项目,在该项目中,我使用了一些独立的组件(我不使用完整的堆栈框架),目前如下所示: psr/log 1.0.0 Common interface for logging libraries sonata-project/intl-bundle 2.2.1 Symfony SonataIntlBundle symfony/debug v2.4.2 Symfony Debug

我目前正在从事一个PHP v5.5.9项目,在该项目中,我使用了一些独立的组件(我使用完整的堆栈框架),目前如下所示:

psr/log                      1.0.0   Common interface for logging libraries
sonata-project/intl-bundle   2.2.1   Symfony SonataIntlBundle
symfony/debug                v2.4.2  Symfony Debug Component
symfony/dependency-injection v2.4.2  Symfony DependencyInjection Component
symfony/event-dispatcher     v2.4.2  Symfony EventDispatcher Component
symfony/form                 v2.4.2  Symfony Form Component
symfony/http-foundation      v2.4.2  Symfony HttpFoundation Component
symfony/http-kernel          v2.4.2  Symfony HttpKernel Component
symfony/icu                  v1.2.0  Contains an excerpt of the ICU data and classes to load it.
symfony/intl                 v2.4.2  A PHP replacement layer for the C intl extension that includes additional data from the ICU library.
symfony/locale               v2.4.2  Symfony Locale Component
symfony/options-resolver     v2.4.2  Symfony OptionsResolver Component
symfony/property-access      v2.4.2  Symfony PropertyAccess Component
symfony/security-core        v2.4.2  Symfony Security Component - Core Library
symfony/security-csrf        v2.4.2  Symfony Security Component - CSRF Library
symfony/templating           v2.4.2  Symfony Templating Component
symfony/translation          v2.4.2  Symfony Translation Component
symfony/twig-bridge          v2.4.2  Symfony Twig Bridge
symfony/validator            v2.4.2  Symfony Validator Component
twig/extensions              v1.0.1  Common additional features for Twig that do not directly belong in core
twig/twig                    v1.15.1 Twig, the flexible, fast, and secure template language for PHP
我有一个实体类、一个FormType类和一个控制器,我能够通过“细枝”模板视图持久化实体。因此,整个堆栈工作正常

然后,我向我的实体添加了一个属性,以便按照官方文档中的描述添加一个图像文件]。我还使用以下代码扩展了FormType:

$builder->add('pictureFile', 'file', array('label' => 'Image File'));
运行更新的代码(选择图像文件)后,将显示以下错误:

Catchable fatal error: Argument 1 passed to MyEntity::setPictureFile() must be an instance of Symfony\Component\HttpFoundation\File\File, array given, called in [.]\vendor\symfony\property-access\Symfony\Component\PropertyAccess\PropertyAccessor.php on line [.] and defined in MyEntity.php on line [.]
因此,Symfony不会从表单自动创建一个数组,而是将
$\u文件
数据绑定到
数组
。我注意到,其他人也有这个问题:

目前,我正在控制器中使用以下代码,但我希望使用自动绑定功能(因为目前我无法验证实体中上载的文件)

编辑(2014-03-03):以下是实体的相关代码:


我找到了问题中描述的问题的解决方案。因为这似乎是很多人都有的问题,我在这个答案中描述了我的解决方案

在我的研究过程中,我遇到了一个虚拟的数据转换器

在阅读了该页面的内容后,我想出了一个想法,用一个定制的DataTransformer来尝试它,它可以将
数组
转换为
上传文件
的实例

以下是逐步解决方案:

  • 使用以下源代码创建一个名为UploadedFileTransformer的文件:

    use Symfony\Component\Form\DataTransformerInterface;
    use Symfony\Component\Form\Exception\TransformationFailedException;
    use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
    use Symfony\Component\HttpFoundation\File\UploadedFile;
    
    
    class UploadedFileTransformer implements DataTransformerInterface
    {
        /**
         * {@inheritdoc}
         *
         * @param array $data The array to transform to an uploaded file.
         *
         * @return \Symfony\Component\HttpFoundation\File\UploadedFile|null The
         *         uploaded file or `null` if no file has been uploaded.
         */
        public function reverseTransform($data)
        {
            if (!$data) {
                return null;
            }
    
            $path = $data['tmp_name'];
            $pathinfo = pathinfo($path);
            $basename = $pathinfo['basename'];
    
            try {
                $uploadedFile = new UploadedFile(
                    $path,
                    $basename,
                    $data['type'],
                    $data['size'],
                    $data['error']
                );
            } catch (FileNotFoundException $ex) {
                throw new TransformationFailedException($ex->getMessage());
            }
    
            return $uploadedFile;
        }
    
        /**
         * {@inheritdoc}
         *
         * @param \Symfony\Component\HttpFoundation\File\UploadedFile|null $file The
         *        uploaded file to transform to an `array`.
         *
         * @return \Symfony\Component\HttpFoundation\File\UploadedFile|null The
         *         argument `$file`.
         */
        public function transform($file)
        {
            return $file;
        }
    }
    
  • 更新FormType以使用
    UploadedFileTransformer
    作为
    文件
    类型输入字段(与问题中的代码进行比较):

  • 从控制器中删除垃圾,在我的示例中是访问
    请求
    对象以获得上传的文件(与问题中的代码进行比较)

  • 就这样。不要摆弄FormType中的属性,实体中的验证也在工作


    我真的不知道,为什么这不是Symfony组件的默认行为?也许我没有在启动代码中注册一些内容?

    只需将多部分添加到表单中,它就可以工作了

    <form action="#" method="post" enctype="multipart/form-data">
    
    </form>
    
    
    
    您的表单是否具有正确的enctype属性?是的,表单按如下方式生成:我有:请参见上文。
    <?php
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolverInterface;
    
    class MyType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder->add('name', 'text')
                ->add(
                    'pictureFile',
                    'file',
                    array('label' => 'Image File')
                )
                ->add('submit', 'submit', array('label' => 'Save'));
        }
    
        public function getName()
        {
            return 'myentity';
        }
    
        public function setDefaultOptions(OptionsResolverInterface $resolver)
        {
            $resolver->setDefaults(array('data_class' => __NAMESPACE__ . '\MyEntity'));
        }
    }
    
    use Symfony\Component\Form\DataTransformerInterface;
    use Symfony\Component\Form\Exception\TransformationFailedException;
    use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
    use Symfony\Component\HttpFoundation\File\UploadedFile;
    
    
    class UploadedFileTransformer implements DataTransformerInterface
    {
        /**
         * {@inheritdoc}
         *
         * @param array $data The array to transform to an uploaded file.
         *
         * @return \Symfony\Component\HttpFoundation\File\UploadedFile|null The
         *         uploaded file or `null` if no file has been uploaded.
         */
        public function reverseTransform($data)
        {
            if (!$data) {
                return null;
            }
    
            $path = $data['tmp_name'];
            $pathinfo = pathinfo($path);
            $basename = $pathinfo['basename'];
    
            try {
                $uploadedFile = new UploadedFile(
                    $path,
                    $basename,
                    $data['type'],
                    $data['size'],
                    $data['error']
                );
            } catch (FileNotFoundException $ex) {
                throw new TransformationFailedException($ex->getMessage());
            }
    
            return $uploadedFile;
        }
    
        /**
         * {@inheritdoc}
         *
         * @param \Symfony\Component\HttpFoundation\File\UploadedFile|null $file The
         *        uploaded file to transform to an `array`.
         *
         * @return \Symfony\Component\HttpFoundation\File\UploadedFile|null The
         *         argument `$file`.
         */
        public function transform($file)
        {
            return $file;
        }
    }
    
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolverInterface;
    
    class MyType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder->add('name', 'text')
                ->add(
                    $builder->create(
                        'pictureFile',
                        'file',
                        array('label' => 'Image File')
                    )->addModelTransformer(new \UploadedFileTransformer)
                )
                ->add('submit', 'submit', array('label' => 'Save'));
        }
    
        public function getName()
        {
            return 'myentity';
        }
    
        public function setDefaultOptions(OptionsResolverInterface $resolver)
        {
            $resolver->setDefaults(array('data_class' => __NAMESPACE__ . '\MyEntity'));
        }
    }
    
    $formType = new MyType;
    $entity = new MyEntity;
    $form = $this->formFactory->create($formType, $entity);
    $form->handleRequest();
    
    if (true === $form->isSubmitted()) {
        if (true === $form->isValid()) {
            $file = $entity->getPictureFile();
    
            // Persist entity, upload file to server and redirect.
        }
    }
    
    // Load View template.
    
    <form action="#" method="post" enctype="multipart/form-data">
    
    </form>