我正在使用Symfony 4.1,但我很难让相对/全路径按我的意愿工作。
在我的数据库中,我有一个Customer实体,其属性称为photo。
<?php
namespace App\Entity;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity(repositoryClass="App\Entity\CustomerRepository")
* @ORM\Table("Customer")
*/
class Customer {
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", nullable=true)
*
* @Assert\File(mimeTypes={ "image/png","image/jpeg" })
*/
private $photo;
public function getPhoto(): ?string
{
return $this->photo;
}
public function setPhoto(?string $photo): self
{
$this->photo = $photo;
return $this;
}
这很有道理,当我用上载照片的方式保存客户时,会按我的期望将照片保存在数据库和文件系统中。
在数据库中,“照片”列将设置为“ 010925c8c427bddca9020197212b64af.png”之类的
这就是我想要的,所以一切都很好。
当我尝试更新现有客户实体时出现问题。 Customer-> getPhoto()将返回相对路径文件名'010925c8c427bddca9020197212b64af.png。
但是该表单未通过验证,它表示此文件不存在。
$em = $this->getDoctrine()->getManager();
$custRepo = $em->getRepository('App:Customer');
$customer = $custRepo->findOneById($id);
$custForm = $this->createForm(CustomerType::class, $customer);
$custForm->handleRequest($request);
if ($custForm->isSubmitted() && $custForm->isValid()) {
$em->flush();
}
它失败了,因为验证没有出现在photos目录中。
这是我的解决方案,它确实有效,但似乎过于骇客。我想知道是否有人对此有更优雅的方法。
$em = $this->getDoctrine()->getManager();
$custRepo = $em->getRepository('App:Customer');
$customer = $custRepo->findOneById($id);
$customer->setPhoto(new File($this->getParameter('photos_dir') .'/' . $customer->getPhoto()));
$custForm = $this->createForm(CustomerType::class, $customer);
$custForm->handleRequest($request);
if ($custForm->isSubmitted() && $custForm->isValid()) {
$photoPathParts = explode('/', $customer->getPhoto());
$customer->setPhoto(array_pop($photoPathParts));
$em->flush();
}
我正在获取照片的完整路径并更新我当前正在处理的实体。这样就可以通过表单验证,但是如果我只保存它,数据库中的路径将更新为照片的完整路径。那不是我想要的,所以我将照片重置为相对路径文件名。
/**
* @ORM\Column(type="string", nullable=true)
*
* @Assert\File(mimeTypes={ "image/png","image/jpeg" })
*/
private $photo;
答案 0 :(得分:1)
看这个例子如何上传图像。该图像位于单独的实体中,您可以将其与客户OneToOne相关。
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* Image
*
* @ORM\Table(name="image")
* @ORM\Entity(repositoryClass="App\Repository\ImageRepository")
* @ORM\HasLifecycleCallbacks
*/
class Image
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(name="extension", type="string", length=180)
*/
private $name;
/**
* @Assert\Image()
*/
public $file;
private $tempFilename;
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function setFile(UploadedFile $file)
{
$this->file = $file;
if (null !== $this->extension) {
$this->tempFilename = $this->name;
$this->extension = null;
$this->name = null;
}
}
public function getFile()
{
return $this->file;
}
/**
* @ORM\PrePersist()
* @ORM\PreUpdate()
*/
public function preUpload()
{
if (null === $this->file) {
return;
}
$extension = $this->file->guessExtension();
$this->name = md5(uniqid('', true)) . '.' . $extension;
}
/**
* @ORM\PostPersist()
* @ORM\PostUpdate()
*/
public function upload()
{
if (null === $this->file) {
return;
}
if (null !== $this->tempFilename) {
$oldFile = $this->getUploadRootDir() . '/' . $this->tempFilename;
if (file_exists($oldFile)) {
unlink($oldFile);
}
}
$this->file->move($this->getUploadRootDir(), $this->name);
}
/**
* @ORM\PreRemove()
*/
public function preRemoveUpload()
{
$this->tempFilename = $this->getUploadRootDir() . '/' . $this->name;
}
/**
* @ORM\PostRemove()
*/
public function removeUpload()
{
if (file_exists($this->tempFilename)) {
unlink($this->tempFilename);
}
}
//folder
public function getUploadDir()
{
return 'uploads/photos';
}
// path to folder web
protected function getUploadRootDir()
{
return __DIR__ . '/../../public/' . $this->getUploadDir();
}
public function getWebPath()
{
return $this->getUploadDir() . '/' . $this->getName();
}
}
ImageFormType
注意::您应该使用formType
中的公共属性$ filepublic function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('file', FileType::class, array(
'label'=> false,
))
;
}