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

Symfony 4多文件上载转换失败异常

  •  0
  • BernardA  · 技术社区  · 6 年前

    我试着跟着 this post (法语)。

    在Symfony的分析器Form上,我可以看到两个文件,每个文件都有自己的错误。摘录如下:

    This value is not valid.    0   Caused by:
    
    ConstraintViolation {#993 ▼
     root: Form {#792 ▶}
     path: "children[attachments].children[0]"
     value: UploadedFile {#36 ▼
       -test: false
       -originalName: "alfa-romeo-4C-1.jpg"
       -mimeType: "image/jpeg"
       -error: 0
       path: "/Applications/MAMP/tmp/php"
       filename: "php0vUzd5"
       basename: "php0vUzd5"
       pathname: "/Applications/MAMP/tmp/php/php0vUzd5"
       ....
     }
    }
    
    TransformationFailedException {#1029 ▼
      #message: "Compound forms expect an array or NULL on submission."
      ....
    

    在React中,我使用formData,代码如下:

    let formData = new FormData();
    formData.append('message[message]', this.props.message_form.values.message.message);
    formData.append('message[ad]', this.props.match.params.ad_id);
    // insert files in formData, if any
    if (this.state.selectedFile.length > 0) {
        const file_length = this.state.selectedFile.length;
        for (let i = 0; i < file_length; i++) {
            formData.append('message[attachments][]', this.state.selectedFile[i]);
        }    
    }
    

    here .

    ["message"]=> array(5) { 
    ["name"]=> array(1) { 
        ["attachments"]=> array(2) { 
            [0]=> string(19) "alfa-romeo-4C-1.jpg" 
            [1]=> string(19) "alfa-romeo-4C-3.jpg" } } 
    ["type"]=> array(1) { 
        ["attachments"]=> array(2) { 
            [0]=> string(10) "image/jpeg" 
            [1]=> string(10) "image/jpeg" } } 
    ["tmp_name"]=> array(1) { 
        ["attachments"]=> array(2) { 
            [0]=> string(36) "/Applications/MAMP/tmp/php/phppPLE3Z" 
            [1]=> string(36) "/Applications/MAMP/tmp/php/phpAF1yQZ" } } 
    ["error"]=> array(1) { 
        ["attachments"]=> array(2) { 
            [0]=> int(0) 
            [1]=> int(0) } } 
    ["size"]=> array(1) { 
        ["attachments"]=> array(2) { 
            [0]=> int(41024) 
            [1]=> int(76577) } } 
    } } 
    

    class Message{
    ... other properties
    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Attachment", mappedBy="message",cascade="all", orphanRemoval=true)
     * @Assert\Valid()
     * @Assert\NotNull()
     */
    private $attachments;
    
    public function __construct()
    {
        $this->attachments = new ArrayCollection();
    }
    ... other methods
    /**
     * @return Collection|Attachment[]
     */
    public function getAttachments(): Collection
    {
        return $this->attachments;
    }
    
    public function addAttachment(Attachment $attachment): self
    {
        if (!$this->attachments->contains($attachment)) {
            $this->attachments[] = $attachment;
            $attachment->setMessage($this);
        }
    
        return $this;
    }
    
    public function removeAttachment(Attachment $attachment): self
    {
        if ($this->attachments->contains($attachment)) {
            $this->attachments->removeElement($attachment);
            // set the owning side to null (unless already changed)
            if ($attachment->getMessage() === $this) {
                $attachment->setMessage(null);
            }
        }
    
        return $this;
    }
    

    附件实体:

    class Attachment
    {
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;
    
    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Message", inversedBy="attachments")
     * @ORM\JoinColumn(nullable=false)
     * @Assert\NotNull()
     */
    private $message;
    
    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     * @Assert\File(mimeTypes={ "image/jpeg" })
     * @Assert\NotNull()
     */
    private $path;
    
    /**
     * Constructor
     *
     * @param Message $message
     */
    public function __construct(Message $message = null)
    {
        $this->message = $message;
    }
    
    public function getId()
    {
        return $this->id;
    }
    
    public function getMessage(): ?Message
    {
        return $this->message;
    }
    
    public function setMessage(?Message $message): self
    {
        $this->message = $message;
    
        return $this;
    }
    
    public function getPath()
    {
        return $this->path;
    }
    
    public function setPath($path)
    {
        $this->path = $path;
    
        return $this;
    }
    }
    

    消息类型:

    $builder
        ->add('message', TextType::class)
        ->add('ad', EntityType::class, array(
                'class' => Ad::class,
             ))
        ->add('attachments', CollectionType::class,array(
                'entry_type' => AttachmentType::class,
                'allow_add' => true,
                'allow_delete' => true,
                'by_reference' => false,
             ));
    

    $builder
        ->add('path', FileType::class, array(
            'multiple' => true,
            ))
        ->add('message', TextType::class, array('label' => 'file'));
    

    最后是MessageController:

     private function insertMessage ($request) {
        $message = new Message();
    
        $form = $this->createForm('App\Form\MessageType', $message);
    
        // get message object and place it as form message content
        $data = $request->request->all();
        $text = $data['message']['message'];
        $message->setMessage($text);
    
        // get/set ad object
        $new_ad = new Ad();
        $ad = $this->ad_repo->findOneById($data['message']['ad']);
        if ($ad instanceof $new_ad) {
            $message->setAd($ad);
        }
    
        //set sender
        isset($this->user) ? 
            $message->setSender($this->user) :
            false;
    
        // get/set receiver
        $receiver_id = $ad->getUser();
        $receiver = $this->userManager->findUserBy(array('id'=>$receiver_id));
        $message->setReceiver($receiver);
    
        $form->handleRequest($request); // that's where the exception is thrown
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   BernardA    6 年前

    我有几个问题:

    在客户端,数组的格式应为:

        let formData = new FormData();
        formData.append('message[message]', this.props.message_form.values.message.message);
        formData.append('message[ad]', this.props.match.params.ad_id);
    
        // insert files in formData, if any
        if (this.state.selectedFile.length > 0) {
            const file_length = this.state.selectedFile.length;
            for (let i = 0; i < file_length; i++) {
                const unique = `message[attachments][${i}][path]`;
                formData.append(unique, this.state.selectedFile[i]);
            }    
        }
    

    附件类型应如下所示:

    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolver;
    use Symfony\Component\Form\Extension\Core\Type\FileType;
    use Symfony\Component\Validator\Constraints\File;
    .....
            $builder
            ->add('path', FileType::class, array(
                'constraints' => array(
                    new File(),
                ),
            ));