Php 文件上传不';无法创建上载的文件
我目前正在从事一个PHP v5.5.9项目,在该项目中,我使用了一些独立的组件(我不使用完整的堆栈框架),目前如下所示: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
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文件
数据绑定到数组
。我注意到,其他人也有这个问题:
我找到了问题中描述的问题的解决方案。因为这似乎是很多人都有的问题,我在这个答案中描述了我的解决方案
在我的研究过程中,我遇到了一个虚拟的数据转换器
在阅读了该页面的内容后,我想出了一个想法,用一个定制的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>