代码之家  ›  专栏  ›  技术社区  ›  Halfstop

symfony维护文件上载的相对路径

  •  0
  • Halfstop  · 技术社区  · 7 年前

    我用的是symfony 4.1,我很难找到我想要的相对/完整的工作路径。

    在我的数据库中,我有一个客户实体,具有一个名为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;
         }
    

    这是有意义的,当我将客户与照片上载一起保存时,它会像我预期的那样将照片保存在数据库和文件系统中。

    在数据库中,照片列将设置为“010925C8C427BDCA9020197212B64AF.png”。

    这就是我想要的,所以一切都很好。

    当我试图更新现有客户实体时,出现了这个问题。客户->getphoto()将返回相对路径文件名“010925C8C427BDCA9020197212B64AF.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();
    }
    

    验证失败,因为验证不在照片目录中。

    这是我的解决方案,它确实有效,但似乎太刻薄了。我不想知道是否有人对此有更优雅的态度。

    $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;
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   hous    7 年前

    看看这个例子如何上传图片。图像位于单独的实体中,您可以将其与客户一一关联。

    <?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();
    }
    
    }
    

    图像格式类型

    NB: 你应该利用公众 属性文件 在表单类型中

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('file', FileType::class, array(
                'label'=> false,
            ))
        ;
    }
    
    推荐文章