Symfony 3 文件上传
Symfony 3 FileUpload
我正在尝试使用 Symfony 3 为我的应用程序实现文件上传功能。
我有一个产品条目,与文件条目有关。
部分产品:
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\File", mappedBy="product")
* @ORM\OrderBy({"weight" = "DESC"})
*/
protected $files;
表单上的字段:
->add('files', FileType::class, array('multiple'=> true, 'data_class'=> 'AppBundle\Entity\File'));
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Product',
));
}
如您所见,我已设置 data_class。
在控制器中我正在尝试处理表单
public function addAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$product = new Product();
$product->setAddedBy($this->getUser());
$form = $this->createForm(ProductType::class, null);
$form->handleRequest($request);
...
我有一个错误:
Expected argument of type "AppBundle\Entity\File", "Symfony\Component\HttpFoundation\File\UploadedFile" given
如果我删除 data_class 映射,我没有错误也没有对象,只有数组。
如何解决此错误,如何将 UploadedFile 转换为 File (Entiry)。我正在尝试创建 Transformer,但我刚得到 ProductEntiry class,结果无法处理它,因为它没有文件。
在进入正题之前,先提一个建议。排队:
$form = $this->createForm(ProductType::class, null);
我会提供 $product
变量,这样它会自动填充数据而不是创建新数据。所以应该改成:
$form = $this->createForm(ProductType::class, $product);
好的,现在,问题出现了,因为你的 Product
class 中可能有一个 setter 像:
public function addFile(AppBundle\Entity\File $file) { ... }
然后,在成功验证之后,表单会尝试用来自表单的数据填充 Product
class 的实例,其中包含 Symfony 的 UploadedFile
class 实例。我希望你明白这一点。
现在,您(至少)有两种可能的解决方案。
您可以为文件字段设置"mapped" => false
选项。这将阻止表单尝试将其值放入基础对象(Product
实例)。
完成后你可以自己处理这个值,即处理文件上传,创建AppBundle/Entity/File
实例并通过setter.[=24将它放入$product
变量中=]
惰性解决方案,但如果您想以其他形式执行相同的操作,则必须将代码复制到需要它的每个控制器。所以仅一次性使用.
更容易
正确的解决方案是首先在 Symfony 的文档中使用 Data Transformer. It's a longer topic to talk about and exact solution depends on your data flow that you want to achieve. Therefore if you want to do this right, read about Data Transformers 将 UploadedFile
转换为您的 File
对象。
我保证,如果您以正确的方式做到这一点,您稍后会感谢自己。我花了一些时间来理解包括数据转换器在内的 Symfony 表单组件,并以这种方式解决了类似的问题。现在它得到了回报。我有可重复使用的图像上传表单,它甚至可以处理删除以前在编辑表单中上传的文件。
P.S。
是 "entity",不是 "entiry"。您已经写了两次 "entiry",所以我只是说一下。
我正在尝试使用 Symfony 3 为我的应用程序实现文件上传功能。 我有一个产品条目,与文件条目有关。 部分产品:
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\File", mappedBy="product")
* @ORM\OrderBy({"weight" = "DESC"})
*/
protected $files;
表单上的字段:
->add('files', FileType::class, array('multiple'=> true, 'data_class'=> 'AppBundle\Entity\File'));
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Product',
));
}
如您所见,我已设置 data_class。
在控制器中我正在尝试处理表单
public function addAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$product = new Product();
$product->setAddedBy($this->getUser());
$form = $this->createForm(ProductType::class, null);
$form->handleRequest($request);
...
我有一个错误:
Expected argument of type "AppBundle\Entity\File", "Symfony\Component\HttpFoundation\File\UploadedFile" given
如果我删除 data_class 映射,我没有错误也没有对象,只有数组。 如何解决此错误,如何将 UploadedFile 转换为 File (Entiry)。我正在尝试创建 Transformer,但我刚得到 ProductEntiry class,结果无法处理它,因为它没有文件。
在进入正题之前,先提一个建议。排队:
$form = $this->createForm(ProductType::class, null);
我会提供 $product
变量,这样它会自动填充数据而不是创建新数据。所以应该改成:
$form = $this->createForm(ProductType::class, $product);
好的,现在,问题出现了,因为你的 Product
class 中可能有一个 setter 像:
public function addFile(AppBundle\Entity\File $file) { ... }
然后,在成功验证之后,表单会尝试用来自表单的数据填充 Product
class 的实例,其中包含 Symfony 的 UploadedFile
class 实例。我希望你明白这一点。
现在,您(至少)有两种可能的解决方案。
您可以为文件字段设置"mapped" => false
选项。这将阻止表单尝试将其值放入基础对象(Product
实例)。
完成后你可以自己处理这个值,即处理文件上传,创建AppBundle/Entity/File
实例并通过setter.[=24将它放入$product
变量中=]
惰性解决方案,但如果您想以其他形式执行相同的操作,则必须将代码复制到需要它的每个控制器。所以仅一次性使用.
更容易正确的解决方案是首先在 Symfony 的文档中使用 Data Transformer. It's a longer topic to talk about and exact solution depends on your data flow that you want to achieve. Therefore if you want to do this right, read about Data Transformers 将 UploadedFile
转换为您的 File
对象。
我保证,如果您以正确的方式做到这一点,您稍后会感谢自己。我花了一些时间来理解包括数据转换器在内的 Symfony 表单组件,并以这种方式解决了类似的问题。现在它得到了回报。我有可重复使用的图像上传表单,它甚至可以处理删除以前在编辑表单中上传的文件。
P.S。 是 "entity",不是 "entiry"。您已经写了两次 "entiry",所以我只是说一下。