我正在尝试将图像作为表单数据字段以及其他字段上传。
我在此link
中关注Symphony的文档
我正在使用FosRestBundle和jms-serializer。
问题是它返回:错误的请求,因为它无法读取图像字段,它始终为空白。
我已经在Postman和Symfony上进行过尝试,但是无论哪种方式它都没有返回积极的反馈。
config.yml
images_directory: '%kernel.project_dir%/web/uploads/images'
service.yml
services:
app.image_uploader:
class: AppBundle\ImageUpload
arguments: ['%images_directory%']
app.doctrine_image_listener:
class: AppBundle\EventListener\UploadImageListener
arguments: ['@app.image_uploader']
tags:
- { name: doctrine.event_listener, event: prePersist }
- { name: doctrine.event_listener, event: preUpdate }
- { name: doctrine.event_listener, event: postLoad }
ImageUpload.php
<?php
namespace AppBundle;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
class ImageUpload
{
private $targetDir;
public function __construct($targetDir)
{
$this->targetDir = $targetDir;
}
public function upload(UploadedFile $file)
{
$fileName = md5(uniqid()).'.'.$file->guessExtension();
try {
$file->move($this->getTargetDir(), $fileName);
} catch (FileException $e) {
// ... handle exception if something happens during file upload
}
return $fileName;
}
public function getTargetDir()
{
return $this->targetDir;
}
}
ImageUploadListener.php
<?php
namespace AppBundle\EventListener;
use AppBundle\Entity\Meuble;
use AppBundle\ImageUpload;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\File\File;
class UploadImageListener
{
private $uploader;
public function __construct(ImageUpload $uploader)
{
$this->uploader = $uploader;
}
public function prePersist(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$this->uploadFile($entity);
}
public function preUpdate(PreUpdateEventArgs $args)
{
$entity = $args->getEntity();
$this->uploadFile($entity);
}
private function uploadFile($entity)
{
// upload only works for Product entities
if (!$entity instanceof Meuble) {
return;
}
$file = $entity->getImage();
// only upload new files
/*if (!$file instanceof UploadedFile) {
return;
}*/
if ($file instanceof UploadedFile) {
$fileName = $this->uploader->upload($file);
$entity->setImage($fileName);
}elseif ($file instanceof File) {
// prevents the full file path being saved on updates
// as the path is set on the postLoad listener
$entity->setImage($file->getFilename());
}
}
public function postLoad(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
if (!$entity instanceof Meuble) {
return;
}
if ($fileName = $entity->getImage()) {
$entity->setImage(new File($this->uploader->getTargetDir().'/'.$fileName));
}
}
}
entity meuble.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Meuble
*
* @ORM\Table(name="meuble")
* @ORM\Entity(repositoryClass="AppBundle\Repository\MeubleRepository")
*/
class Meuble
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=20)
*/
private $name;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Piece", inversedBy="meubles")
* @var Piece
*/
private $piece;
/**
* @var int
*
* @ORM\Column(name="volume", type="integer")
*/
private $volume;
/**
* @var string
*
* @ORM\Column(name="image",type="string")
* @Assert\NotBlank(message="Please, upload the photo.")
* @Assert\File(
* mimeTypes={ "image/png", "image/jpg", "image/jpeg" },
* mimeTypesMessage="Please upload a valid image")
*/
private $image;
public function getImage()
{
return $this->image;
}
public function setImage($image)
{
$this->image = $image;
return $this;
}
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
*
* @return Meuble
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @return mixed
*/
public function getVolume()
{
return $this->volume;
}
/**
* @param mixed $volume
*/
public function setVolume($volume)
{
$this->volume = $volume;
}
/**
* @return Piece
*/
public function getPiece()
{
return $this->piece;
}
/**
* @param Piece $piece
*/
public function setPiece($piece)
{
$this->piece = $piece;
}
}
MeubleType.php
<?php
/**
* Created by PhpStorm.
* User: KHALED
* Date: 13/03/2019
* Time: 15:34
*/
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class MeubleType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name');
$builder->add('volume');
$builder->add('image', FileType::class, ['label' => 'Image (JPG ou PNG)']);
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Meuble',
'csrf_protection' => false
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_meuble';
}
}
controller.php
/**
* @Rest\View(statusCode=Response::HTTP_CREATED, serializerGroups={"meuble"})
* @Rest\Post("/{id}/meuble/new")
*/
public function addMeubleAction(Request $request)
{
$piece = $this->get('doctrine.orm.entity_manager')
->getRepository('AppBundle:Piece')
->find($request->get('id'));
/* @var $piece Piece */
if (empty($piece)) {
return $this->pieceNotFound();
}
$meuble = new Meuble();
$meuble->setPiece($piece);
//$meuble->setImage($request->files->all()['image']);
/* $uploadedImage=$request->files->get('file');
$meuble->setImage($uploadedImage);*/
//$meuble->setImage($request->files->all()['image']);
$form = $this->createForm(MeubleType::class, $meuble);
// Le paramétre false dit à Symfony de garder les valeurs dans notre
// entité si l'utilisateur n'en fournit pas une dans sa requête
$form->submit($request->request->all());
//$form->handleRequest($request);
//if ($form->isValid()&& $form->isSubmitted()) {
if ($form->isValid()) {
/*
* /**
* @var UploadedFile $file
*
* $file=$meuble->getImage();
$fileName = md5(uniqid()).'.'.$file->guessExtension();
$file->move($this->getParameter('images_directory'), $fileName);
$meuble->setImage($fileName);*/
/*$file = $meuble->getImage();
$fileName = $imageUpload->upload($file);
$meuble->setImage($fileName);*/
$em = $this->get('doctrine.orm.entity_manager');
$em->persist($meuble);
$em->flush();
return $meuble;
} else {
return $form;
}
}
序列化Entity.Meuble.yml
AppBundle\Entity\Meuble:
exclusion_policy: none
properties:
id:
groups: ['quantite','meuble','devis','piece']
name:
groups: ['quantite','meuble','devis','piece']
volume:
groups: ['quantite','meuble','devis','piece']
image:
groups: ['quantite','meuble','devis','piece']
piece:
groups: ['meuble']
我希望输出为200 ok,并且可以存储图像并且可以对其进行可视化,但是实际输出为400“消息”:“验证失败” postman response