【发布时间】:2018-07-12 07:08:07
【问题描述】:
我的主页横幅上有四张图片,我希望能够不时使用 Symfony 表单更新它们。
我完全按照 Vich Uploader 文档中的描述设置了一个 Image 实体(带有更新的 At-Entity 和所有内容)
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* Image
*
* @ORM\Table(name="app_image")
* @ORM\Entity
* @Vich\Uploadable
*/
class Image {
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @Vich\UploadableField(mapping="dashboard", fileNameProperty="imageName", size="imageSize")
*
* @var File
*/
private $imageFile;
/**
* @ORM\Column(type="integer")
*
* @var integer
*/
private $imageSize;
/**
* @var string
* @ORM\Column(type="string", nullable=false)
*/
private $imageName;
/**
* @ORM\Column(type="datetime")
*
* @var \DateTime
*/
private $updatedAt;
/**
* @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $image
*/
public function setImageFile(?File $image = null): void
{
$this->imageFile = $image;
if (null !== $image) {
$this->updatedAt = new \DateTimeImmutable();
}
}
public function getImageFile(): ?File
{
return $this->imageFile;
}
public function setImageName(?string $imageName): void
{
$this->imageName = $imageName;
}
public function getImageName(): ?string
{
return $this->imageName;
}
public function setImageSize(?int $imageSize): void
{
$this->imageSize = $imageSize;
}
public function getImageSize(): ?int
{
return $this->imageSize;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set updatedAt
*
* @param \DateTime $updatedAt
*
* @return Image
*/
public function setUpdatedAt($updatedAt)
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* Get updatedAt
*
* @return \DateTime
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
}
由于四个图像已经存在,我只添加了一个动作来将图像更新到我的控制器
/**
* @Route("/uploadImage/{id}", name="appBundle_upload_image", requirements={"id" = "\d+"})
* @Security("is_granted('ROLE_ATTACHEMENT_ADMIN')")
*/
public function uploadAction(Request $request, $id){
$repository = $this->getDoctrine()->getRepository('AppBundle:Image');
$em = $this->getDoctrine ()->getManager ();
$image = $repository->findOneById($id);
$form = $this->createForm(UploadImageType::class, $image);
$form->handleRequest($request);
if ($form->isValid() ) {
$em->flush();
return $this->redirectToRoute('index');
}
return $this->render('AppBundle:Image:upload.html.twig', array(
'form' => $form->createView(),
'image' => $image,
));
}
我的数据库表中已经有一些图片,所以我可以访问到我的控制器操作的路由,呈现的表单仅包含以下内容:
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add('imageFile', VichImageType::class, [
'required' => false,
'allow_delete' => false,
'download_label' => '...',
'download_uri' => true,
'image_uri' => true,
]);
}
如您所见,我还没有对基本文档进行太多更改。 无论如何,当去那条路线时,例如ID 7,图片7显示在download_uri下,转储imageName或UpdateAt时,与我的数据库表中显示的数据相同。但是当我尝试上传一张应该替换旧图片的新图片时,我收到一个错误提示
实体 AppBundle\Entity\Image@0000000075aa1d6c00000000789d890b 不受管理。如果实体从数据库中获取或通过 EntityManager#persist 注册为新实体,则该实体被管理
或者有时它会像奇迹一样发生,我被重定向,但我的数据库表中没有任何变化,所以旧图片没有被替换或任何东西。
我搜索了很多,找到了很多Entity not managed错误的解决方案,或者因为没有属性更改而没有更新。但他们都没有真正解决我的问题。
您是否在我的代码中看到任何可能导致问题的内容?
更新
我将 @nifr 的 setImageFile 方法添加到我的图像实体中:
/**
* @param File|UploadedFile|null $imageFile
*
* @return $this
*/
public function setImageFile(File $imageFile = null)
{
$this->imageFile = $imageFile;
dump($imageFile);
if ($imageFile instanceof UploadedFile) {
$this->setFileSize($imageFile->getClientSize());
$this->setMimeType($imageFile->getClientMimeType());
$this->setOriginalName($imageFile->getClientOriginalName());
$this->updatedAt = new \DateTime();
}
return $this;
}
在 if 条件内转储时,它什么也不做,因此显然它不会将 $imageFile 识别为 UploadedFile 的实例。但是,在此之前转储时(如在复制的代码中),它会转储以下信息:
UploadedFile {#14 ▼
-test: false
-originalName: "Route.png"
-mimeType: "image/png"
-size: 13218
-error: 0
path: "/tmp"
filename: "phpQhWrTd"
basename: "phpQhWrTd"
pathname: "/tmp/phpQhWrTd"
extension: ""
realPath: "/tmp/phpQhWrTd"
aTime: 2018-02-05 19:03:12
mTime: 2018-02-05 19:03:12
cTime: 2018-02-05 19:03:12
inode: 311536
size: 13218
perms: 0100600
owner: 1001
group: 33
type: "file"
writable: true
readable: true
executable: false
file: true
dir: false
link: false
}
显然它来自“UploadedFile”。有什么想法吗?
我也尝试过在我的控制器中转储:
public function uploadAction(Request $request, $id){
$repository = $this->getDoctrine()->getRepository('AppBundle:Image');
$em = $this->getDoctrine ()->getManager ();
$image = $repository->findOneById($id);
dump($image);
$form = $this->createForm(UploadImageType::class, $image);
$form->handleRequest($request);
if ($form->isValid() && $form->isValid() ) {
dump($image->getImageName());
$em->flush();
return $this->redirectToRoute('index');
}
return $this->render('AppBundle:Image:upload.html.twig', array(
'form' => $form->createView(),
'image' => $image,
));
}
在 imageFile Setter 中有转储我意识到,我在控制器中的转储包含“旧”图像名称,例如名称 A 但 Setter 包含“新”图像名称(来自应该替换旧图像的图像),所以实际上是正确的。但它永远不会更新。
【问题讨论】:
-
你的图片的架构结构是什么,例如
describe images等你的问题 -
我添加了一些代码 - 虽然它不能直接回答您的问题 - 可能会帮助其他用户在将来通过
vich-uploader-bundle更新文件时遇到问题。您是否设法解决了您的问题? -
@sakhunzai 抱歉,我想我没有 100% 得到你的问题,你能换个方式再问一遍吗?
-
@nifr 不,我还没有解决我的问题,但仍会很高兴得到帮助!
-
我正在查看您的数据库表中是否有
updatedAt列,如下面的 nifr 回答
标签: image symfony vichuploaderbundle