呈现包含文件类型的 Symfony 4 编辑表单时出错

error when rendering Symfony 4 edit form that includes a File type

我正在按照本文档 https://symfony.com/doc/current/controller/upload_file.html 中列出的步骤来允许上传文件。它非常适合添加新项目,但是当我尝试编辑我的实体时,出现以下错误:

表单的视图数据应该是 class Symfony\Component\HttpFoundation\File\File 的一个实例,但却是一个 (n) 字符串。您可以通过将 "data_class" 选项设置为 null 或添加一个将 (n) 字符串转换为 Symfony\Component\HttpFoundation\File\File.

实例的视图转换器来避免此错误

我已经尝试使用该文章中建议的代码,在我的更新方法中将文件夹路径作为文件类型附加到实体,如下所示:

public function editAction(Request $request, Advertiser $advertiser)
{

    $advertiser->setLogo(
        new File($this->getParameter('logo_directory') .'/' . $advertiser->getLogo())
    );

    $editForm = $this->createForm(AdvertiserType::class, $advertiser);

    $editForm->handleRequest($request);
    if ($editForm->isSubmitted() && $editForm->isValid()) {
        $this->getDoctrine()->getManager()->flush();
        return $this->redirectToRoute('advertiser_list');
    }
    return $this->render('advertiser/index.html.twig', [
        'form' => $editForm->createView()
    ]);
}

logo_directory 参数已正确定义(并且可以很好地创建新实体)。

如果您有任何想法,请告诉我我做错了什么。

感谢您的帮助。

更新:在这篇文章 中,有一个提议的解决方案是在表单构建器代码中包含以下内容:

->add('file', FileType::class, array('data_class' => null))

所以我现在正在这样做,编辑表单将显示 - 但它不会预先填充之前的选择。

->add('logo', FileType::class, array('data_class' => null), ['label' => 'Logo (JPG or PNG file)'])

有没有想过如何更改它以允许表单显示之前预填充的选择?

设置空 data_class 将删除警告,但它不会起作用,此时您不需要它。

这是因为一旦您的文件被持久化,保留在数据库中的只是一个路径,而不是文件本身(它在磁盘上);

如果要再次编辑此实体,路径(字符串)必须再次转换为文件实体;这就是错误消息所说的。

.. 这就是你写的时候所做的:

$advertiser->setLogo(
    new File($this->getParameter('logo_directory') .'/' . $advertiser->getLogo())
);

现在,剩下的问题是您要预填充文件字段。事实上,这是不可能的,因为文件字段指向你自己电脑中的一个位置,而不是你服务器上的文件(而且你不能像那样自动从别人的电脑上传东西,那会很危险).

您想要做的可能是指示文件已存储,获取其路径并可能将其显示给您的用户。

所以在你的 Twig 模板中,类似的东西(更改为你的真实徽标目录):

{% if form.logo.vars.data %}
  <img src="{{ asset('/uploads/logos_directory/' ~ form.logo.vars.data.filename) }}"/>
{% endif %}

希望清楚。