[英]Symfony maintaining relative path for file uploads
我使用的是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;
看這個例子,如何上傳圖片。 該圖像位於單獨的實體中,您可以將其與客戶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的公共屬性$ file
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('file', FileType::class, array(
'label'=> false,
))
;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.