我使用Symfony2和wamp服务器。我尝试在之后实现上传方法。
我有两个实体:DocumentsEnsemble.php和Ensembles.php。DocumentsEnsembles是I存储上传文件的实体,用于1集成(图像、文档、pdf等)。集成可以有0或多个文档,而文档可以属于0或1单个集成。
这是我的实体代码,名为Ensembles.php:
namespace MySpace\DatabaseBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\UploadedFile;
/**
* Ensembles
*
* @ORM\Table(name="ensembles")
* @ORM\Entity
*/
class Ensembles
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="nom", type="string", length=150, nullable=false)
*/
private $nom;
/**
* @ORM\ManyToOne(targetEntity="Documentsensemble", inversedBy="file")
* @ORM\JoinColumn(name="documentsensemble_id", referencedColumnName="id", nullable=true)
*/
private $documentsensemble;
//the getters and setters
//implement Upload method
public function preUpload()
{
if (null !== $this->file) {
$this->path = sha1(uniqid(mt_rand(), true)).'.'.$this->file->guessExtension();
}
}
/**
* @ORM\PostPersist()
* @ORM\PostUpdate()
*/
public function upload()
{
if (null === $this->file) {
return;
}
$this->file->move($this->getUploadRootDir(), $this->path);
unset($this->file);
}
/**
* @ORM\PostRemove()
*/
public function removeUpload()
{
if ($file = $this->getAbsolutePath()) {
unlink($file);
}
}我想实现上传的方法,就像你可以在成群看到。这是名为DocumentsEnsemble的DocumentsEnsembles.php实体
namespace MySpace\DatabaseBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\UploadedFile;
/**
* Documentsensemble
*
* @ORM\Table(name="documentsensemble")
* @ORM\Entity
* @ORM\HasLifecycleCallbacks
*/
class Documentsensemble
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
* @Assert\NotBlank
*/
public $nom;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
public $path; //La propriété path stocke le chemin relatif du fichier et est persistée dans la base de données
public function getAbsolutePath()
{
return null === $this->path ? null : $this->getUploadRootDir().'/'.$this->path;
}
public function getWebPath()
{
return null === $this->path ? null : $this->getUploadDir().'/'.$this->path;
}
protected function getUploadRootDir()
{
return __DIR__.'src/MySpace/WelcomeBundle/Ressources/public/image/uploadEnsembles'.$this->getUploadDir();
}
protected function getUploadDir()
{
return 'uploads/documents';
}
/**
* @Assert\File(maxSize="4M")
* @ORM\OneToMany(targetEntity="Ensembles", mappedBy="documentsensemble")
*/
public $file;
// the getters and setters在一个使用post方法的表单中,我可以在我的集合实体中添加一个集合。此表单包含要上载属于集合的文件的输入文件。我使用一个名为EnsemblesType.php的Doctrine生成的表单,这是用于:
namespace MySpace\DatabaseBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class EnsemblesType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('referenceclient')
->add('nom')
->add('voie')
->add('numerovoie')
->add('codepostal')
->add('commune')
->add('dateactivation','date', array(
'widget' => 'single_text',
'format' => 'yyyy-MM-dd',
'attr' => array('class' => 'datepicker')
))
->add('datedesactivation', 'date', array(
'widget' => 'single_text',
'format' => 'yyyy-MM-dd',
'attr' => array('class' => 'datepicker')
))
->add('documentsensemble', 'file')
->add('parcsimmobilier')
->add('systemes')
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'MySpace\DatabaseBundle\Entity\Ensembles'
));
}
/**
* @return string
*/
public function getName()
{
return 'MySpace_databasebundle_ensembles';
}
}这是带有post方法的表单的addEnsembles.html.twig:
<form action="{{ path('ajouterEnsembles_process') }}" method="post" {{ form_enctype(formEnsemble) }}>
{{ form_errors(formEnsemble) }}
<div>
{{ form_label(formEnsemble.nom, "Nom de l'ensemble:", {'label_attr': {'class': 'control-label'}}) }}
{{ form_errors(formEnsemble.nom) }}
<div>
{{ form_widget(formEnsemble.nom, {'attr': {'class': 'form-control'}}) }}
</div>
</div>
<br>
{# Upload #}
<div class="container">
<div class="row col-md-12">
<div class="row col-md-9">
{{ form_label(formEnsemble.documentsensemble, "Transférer un fichier appartenant à cet ensemble:", {'label_attr': {'class': 'control-label'}}) }}
<div>
{{ form_widget(formEnsemble.documentsensemble) }}
</div>
</div>
<br>
{# validation #}
<div class="row col-md-3">
<input type="submit" value="Ajouter" class="btn btn-success"/>
</div>
</div>
</div>
</form>当我提交我的表单时,我有以下错误:
可捕获的致命错误:传递给MySpace\DatabaseBundle\Entity\Ensembles::setDocumentsensemble()的参数1必须是给定的Symfony\Component\HttpFoundation\File\UploadedFile实例的实例,在第438行的C:\wamp\www\BitbucketRepository\repos\SymfonyGirusMySpace\vendor\symfony\symfony\src\Symfony\Component\PropertyAccess\PropertyAccessor.php中调用,在C:\wamp\www\BitbucketRepository\repos\SymfonyGirusMySpace\src\MySpace\DatabaseBundle\Entity\Ensembles.php第411行中定义。
有人能解释我才能找到正确的解决方案吗?我对上传文件的方法做得对吗?
这是我的控制器方法,用于添加一个包含上传文件的集合:
public function addEnsemblesAction() {
$em=$this->getDoctrine()->getManager();
$ensemble = new Ensembles;
$formEnsemble=$this->createForm(new EnsemblesType(), $ensemble);
$request = $this->getRequest();
if ($request->isMethod('POST') | ($formEnsemble->isValid())) {
$formEnsemble->bind($request);
$ensemble = $formEnsemble->getData();
$em->persist($ensemble);
$em->flush();
return $this->redirect($this->generateUrl('showEnsembles'));
}
else {
return $this->render('MySpaceGestionPatrimoinesBundle:Ensembles:addrEnsembles.html.twig', array('formEnsemble' => $formEnsemble->createView() ));
}
}更新问题以求解决
感谢Abdallah Arffak的回答和评论
事实上,我改变了我的两个提子之间的关系。实际上,上传方法必须在Documentsensemble.php中。
这是Ensembles.php的代码:
namespace MySpace\DatabaseBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\UploadedFile;
/**
* Ensembles
*
* @ORM\Table(name="ensembles")
* @ORM\Entity
*/
class Ensembles
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="nom", type="string", length=150, nullable=false)
*/
private $nom;
// The getters and setters现在使用upload方法(回调等.)编写Documentsensembles.php代码:
namespace MySpace\DatabaseBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\UploadedFile;
/**
* Documentsensemble
*
* @ORM\HasLifecycleCallbacks
* @ORM\Table(name="documentsensemble", indexes={@ORM\Index(name="IDX_674FC05E5BA556D3", columns={"ensembles_id"})})
* @ORM\Entity
*/
class Documentsensemble
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="nom", type="string", length=255, nullable=false)
* @Assert\NotBlank
*/
private $nom;
/**
* @var string
*
* @ORM\Column(name="path", type="string", length=255, nullable=true)
*/
private $path; //stocke le chemin relatif du fichier et est persistée dans la base de données
/**
* @Assert\File(maxSize="6000000")
*/
public $file;
// UPLOAD
public function getWebPath()
{
return null === $this->path ? null : $this->getUploadDir().'/'.$this->path;
}
protected function getUploadRootDir()
{
// le chemin absolu du répertoire où les documents uploadés doivent être sauvegardés
return __DIR__.'/../../../../MySpace/'.$this->getUploadDir();
}
protected function getUploadDir()
{
// on se débarrasse de « __DIR__ » afin de ne pas avoir de problème lorsqu'on affiche le document/image dans la vue.
return 'uploads/documentsEnsemble';
}
// propriété utilisé temporairement pour la suppression
private $filenameForRemove;
/**
* @ORM\PrePersist()
* @ORM\PreUpdate()
*/
public function preUpload()
{
if (null !== $this->file) {
$this->path = $this->file->guessExtension();
}
}
/**
* @ORM\PostPersist()
* @ORM\PostUpdate()
*/
public function upload()
{
if (null === $this->file) {
return;
}
// lancer une exception ici si le fichier ne peut pas être déplacé afin que l'entité ne soit pas persistée dans la base de données comme le fait la méthode move() de UploadedFile
$this->file->move($this->getUploadRootDir(), $this->nom.'.'.$this->file->guessExtension());
unset($this->file);
}
/**
* @ORM\PreRemove()
*/
public function storeFilenameForRemove()
{
$this->filenameForRemove = $this->getAbsolutePath();
}
/**
* @ORM\PostRemove()
*/
public function removeUpload()
{
if ($this->filenameForRemove) {
unlink($this->filenameForRemove);
}
}
public function getAbsolutePath()
{
return null === $this->path ? null : $this->getUploadRootDir().'/'.$this->nom.'.'.$this->path = $this->file->guessExtension();
}
// The getters and the setters现在是控制器的代码:
public function uploadAction() {
$message = "Infos: aucun documents uploadé présent pour le moment";
$em=$this->getDoctrine()->getManager();
$documentsensemble = $em->getRepository('MySpaceDatabaseBundle:Documentsensemble');
$documentsensemble = new Documentsensemble();
$formUpload = $this->createForm(new DocumentsensembleType(), $documentsensemble);
$requestUpload = $this->getRequest();
//instruction if à plusieurs conditions: ici si la method est POST et si le formulaire est valide
if ($requestUpload->isMethod('POST') | ($formUpload->isValid())) {
$formUpload->bind($requestUpload);
$documentsensemble = $formUpload->getData();
//$documentsensemble->upload();
//Cette ligtne est commenté car nous utilisons les callbacks pour la méthode Upload de Symfony
$em->persist($documentsensemble);
$em->flush();
return $this->redirect($this->generateUrl('MySpace_formulaire_recherche_ensembles'));
}
//retourner le formulaire d'ajout si c'est invalide
else {
return $this->render('MySpaceGestionPatrimoinesBundle:Ensembles:documentsensemble.html.twig', array('formUpload' => $formUpload->createView(), 'message' => $message ));
}
}最后,我在另一个表单中调用表单,有很多方法和方法可以这样做,比如检查西佛尼烹饪书或这里,就像Abdallah Arffak建议的那样。
非常感谢,如果我的英语不好,很抱歉。
发布于 2014-12-29 14:11:22
你应该用这个
{{ form_label(formEnsemble.file, "Transférer un fichier appartenant à cet ensemble:", {'label_attr': {'class': 'control-label'}}) }}
<div>
{{ form_widget(formEnsemble.file) }}
</div>
</div>而不是这个
{{ form_label(formEnsemble.documentsensemble, "Transférer un fichier appartenant à cet ensemble:", {'label_attr': {'class': 'control-label'}}) }}
<div>
{{ form_widget(formEnsemble.documentsensemble) }}
</div>
</div>https://stackoverflow.com/questions/27688888
复制相似问题