簡體   English   中英

Symfony維護文件上傳的相對路徑

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM