在Symfony2上

时间:2017-02-07 18:28:22

标签: php forms symfony file-upload

我正在研究Symfony2.8,我想在我的产品控制器的createAction中上传图像但我无法获取FileUpload对象来移动文件服务器。我只能将fileName作为字符串访问。

的appbundle /实体/图像

<?php
namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Image
 *
 * @ORM\Table(name="app_image")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\ImageRepository")
 */
class Image
{

    /**
     * @var int
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     * @ORM\Column(name="imageName", type="string", length=255, unique=true, nullable=true)
     * 
     */
    private $imageName;

    // getters & setters
/**
 * Get id
 * @return int
 */
public function getId()
{
    return $this->id;
}

/**
 * Set imageName
 * @param string $imageName
 * @return Image
 */
public function setImageName($imageName)
{
    $this->imageName = $imageName;
    return $this;
}

/**
 * Get imageName
 * @return string
 */
public function getImageName()
{
    return $this->imageName;
}

/**
 * Set isLocked
 * @param boolean $isLocked
 * @return Image
 */
public function setIsLocked($isLocked)
{
    $this->isLocked = $isLocked;
    return $this;
}

/**
 * Get isLocked
 * @return bool
 */
public function getIsLocked()
{
    return $this->isLocked;
}

public function getUrl(){
    if($this->imageName == null || $this->imageName == "" || $this->imageName == self::DEFAULT_NAME){
        $imgName = self::DEFAULT_NAME;
    }else{
        $imgName = $this->imageName;
    }
    return getcwd().'/uploads/images/'.$imgName;
}
}

的appbundle /实体/ ShopProduct

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use AppBundle\Entity\Shop;
/**
 * ShopProduct
 *
 * @ORM\Table(name="app_shop_product")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\ShopProductRepository")
 */
class ShopProduct
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var bool
     *
     * @ORM\Column(name="isBio", type="boolean")
     */
    private $isBio;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;

    /**
     * @var string
     * @ORM\Column(name="price", type="string", length=255)
     */
    private $price;

    /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Shop")
     * @ORM\JoinColumn(nullable=false)
     */
    private $shop;

    /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Product", cascade={"persist"})
     * @ORM\JoinColumn(nullable=false)
     */
    private $product;

    /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Image", cascade={"persist"})
     * @ORM\JoinColumn(nullable=true)
     */
    private $image;

    /**
     * @var string
     *
     * @ORM\Column(name="composition", type="string", length=255)
     */
    private $composition;

    /**
     * @var string
     *
     * @ORM\Column(name="origin_transform", type="string", length=255)
     */
    private $originTransform;

    /**
     * @var string
     *
     * @ORM\Column(name="origin_region", type="string", length=255)
     */
    private $originRegion;

    /**
     * @var string
     *
     * @ORM\Column(name="origin_country", type="string", length=255)
     */
    private $originPays;


    public function __construct(Shop $shop = null)
    {
        if($shop != null){
            $this->shop = $shop;
        }
    }

    /*
     * get originPays
     * return Obj
     */
    public function getOriginPays() 
    {
      return $this->originPays;
    }

    /*
     * set originPays
     */
    public function setOriginPays($originPays) 
    {
      $this->originPays = $originPays;
    }

    /*
     * get originRegion
     * return Obj
     */
    public function getOriginRegion() 
    {
      return $this->originRegion;
    }

    /*
     * set originRegion
     */
    public function setOriginRegion($originRegion) 
    {
      $this->originRegion = $originRegion;
    }

    /*
     * get originTransform
     * return Obj
     */
    public function getOriginTransform() 
    {
      return $this->originTransform;
    }

    /*
     * set originTransform
     */
    public function setOriginTransform($originTransform) 
    {
      $this->originTransform = $originTransform;
    }
    /*
     * get composition
     * return Obj
     */
    public function getComposition() 
    {
      return $this->composition;
    }

    /*
     * set composition
     */
    public function setComposition($composition) 
    {
      $this->composition = $composition;
    }


    /**
     * Get id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set isBio
     *
     * @param boolean $isBio
     *
     * @return ShopProduct
     */
    public function setIsBio($isBio)
    {
        $this->isBio = $isBio;

        return $this;
    }

    /**
     * Get isBio
     *
     * @return bool
     */
    public function getIsBio()
    {
        return $this->isBio;
    }

    /**
     * Set name
     *
     * @param string $name
     *
     * @return ShopProduct
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * 
     * @param Product $product
     * @return \AppBundle\Entity\ShopProduct
     */
    public function setProduct(Product $product)
    {
        $this->product = $product;
        return $this;
    }

    /**
     * 
     */
    public function getProduct()
    {
        return $this->product;
    }

    /**
     * 
     * @param Shop $shop
     * @return \AppBundle\Entity\ShopProduct
     */
    public function setShop(Shop $shop)
    {
        $this->shop = $shop;
        return $this;
    }

    /**
     * 
     */
    public function getShop()
    {
        return $this->shop;
    }

    /**
     * 
     * @param Image $image
     * @return \AppBundle\Entity\ShopProduct
     */
    public function setImage(Image $image)
    {
        $this->image = $image;
        return $this;
    }

    /**
     * 
     */
    public function getImage()
    {
        return $this->image;
    }


    /*
     * get price
     * return Obj
     */
    public function getPrice()
    {
        return $this->price;
    }

    /*
     * set price
     */
    public function setPrice($price)
    {
        $this->price = $price;
    }

}

在我的控制器中,我根据产品的自定义表单创建了Form。产品

的appbundle /控制器/ ProductController.php

public function createAction(Request $request){
    $user = $this->get('security.context')->getToken()->getUser();

    $em         = $this->getDoctrine()->getManager();
    $shop       = $em->getRepository('AppBundle:Shop')->findOneBy(array("owner"=>$user->getId()));

    $shopProduct = new ShopProduct($shop);

    $form = $this->createForm(ShopProductType::class, $shopProduct);
    $form->handleRequest($request);

    if ($form->isSubmitted()) {
        if ($form->isValid()) {

            $shopProduct    = $form->getData();

            $image = $shopProduct->getImage()->getImageName();
            if($image != null){
                $fileName = 'sprod_'.$shop->getId().'_'.md5(uniqid()).$image->guessExtension();
                $image->move($this->getParameter('produits_directory'), $fileName);
                $shopProduct->getImage()->setImageName($fileName);
            }

            $em->persist($shopProduct);
            $em->flush();           
            return $this->redirectToRoute('pro_product');
        }
    }

    return $this->render('BoBundle:Products:new-product.html.twig', array(
            "form" => $form->createView()
    ));
}

问题是,当我按照Symfony2 documentation for the file uploads中的说明尝试使用我的文件时,我收到错误消息:

  

在字符串

上调用成员函数guessExtension()

imageName属性是表单发送的图像的名称,在我的例子中,它应该是FileUpload对象。

的appbundle /形式/ ShopProductType.php

<?php
namespace AppBundle\Form;
use AppBundle\Form\ImageType;

class ShopProductType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('image', ImageType::class, array('required' => false))
            //etc
    }
}

//的appbundle /形式/ ImageType.php

use Symfony\Component\Form\Extension\Core\Type\FileType;

class ImageType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('imageName', FileType::class, array('label' => 'Logo' , 'attr' => array('accept' , 'image/x-png,image/gif,image/jpeg,image/jpg')));
    }

编辑:

这是我的表单视图:

<form id="login-form" action="{{ path("pro_product_create") }}" method="post">
    {{ form_errors(form) }}
    {{ form_widget(form._token) }}
    <div class="row">
        <div class="form-group">
        <label for="appbundle_shopproduct_image_imageName" class="form-label">Image produit</label><br>
        <div class="modal-astuce">
            <i>Si vous ne choisissez pas d’image, par défaut nous en sélectionnerons une dans notre banque d’images en fonction du nom du produit.</i>
        </div>
        <div class="row row-image-product">
            <a class="greybtn abtn upload-img-btn" onClick="$('#appbundle_shopproduct_image_imageName').trigger('click');selectimg('1');">
            <i class="fa fa-upload" aria-hidden="true" style="margin-right: 15px;"></i>Uploader une image
            </a>
            <i id="check1" class="fa fa-check" aria-hidden="true"></i><br/>
        </div>
            <span id="filename"></span>
            <input  type="file" id="appbundle_shopproduct_image_imageName" name="appbundle_shopproduct[image][imageName]" accept="image/x-png,image/gif,image/jpeg,image/jpg" style="display:none">
        </div>
    </div>        
    <div class="row">
        {{ form_row(form.name) }}
    </div>        
    <div class="row center row-submit">
        <input class="btn-yellow" id="" name="_submit" type="submit" value="Valider">
    </div>
</form>    

1 个答案:

答案 0 :(得分:0)

问题出在表单属性中。要上传文件,我们必须在表单中添加enctype="multipart/form-data"

我只需更正添加enctype的表单:

<form id="login-form" action="{{ path("pro_product_create") }}" method="post" {{ form_enctype(form) }}>

更好的方法是使用{{ form_start(form) }}打印表单,因为生成了关于表单中包含的输入类型的enctype:

{{ form_start(form) }}
     <!-- Form content -->
{{ form_end(form) }}

谢谢@sentenza