Symfony使用原理更新和删除多个文件 [英] Symfony Update and delete multiple files using doctrine
问题描述
我正在尝试更新(多个)上传的文件
I am trying to Update (multiple) uploaded files
我遇到两个问题。当我尝试从index.html树枝输入编辑表单时,出现以下错误:
I am having two problems. When I try to enter the edit form from index.html twig it gives me the following error:
该表单的视图数据预计为类Symfony,Component,HttpFoundation,File,File的实例,但为字符串。您可以通过将 data_class选项设置为null或添加一个将a(n)字符串转换为Symfony\Component\HttpFoundation\File\File实例的视图转换器来避免此错误。
The form's view data is expected to be an instance of class Symfony\Component\HttpFoundation\File\File, but is a(n) string. You can avoid this error by setting the "data_class" option to null or by adding a view transformer that transforms a(n) string to an instance of Symfony\Component\HttpFoundation\File\File.
我尝试将data_class选项设置为null,但它又给出了另一个错误,它没有用。
I tried to set data_class option to null but it gave another error it didn't work.
所以不是在我尝试更新时,而是在我尝试进入编辑表单时。我已经尝试了其他有关堆栈溢出的其他问题的多种解决方案,但我一直收到此错误。
So not when I try to update but when I try to go to the edit form. I have tried multiple solution from other questions on stack overflow but I keep getting this error.
第二个问题是当我尝试删除文件时,它仅从以下位置删除数据库而不是文件。我知道删除时没有提到文件的位置。我不知道该怎么做。我已经看到了一些Symfony 2的示例,但是当我尝试过时它没有用。有人可以帮我解决这些问题吗?
Second problem is at the moment when I try to delete file, it only delete from database not the file. I know I haven't Referred to the location of the file when I delete. I don't know how to do that. I have seen some examples of Symfony 2 but it didn't work when I tried. Can someone help me fix these problems?
编辑
我已经设置了FileType $ builder-> add('file',FileType :: class,array('data_class'=> null,'by_reference'=> false,));
多次清除现金后,我可以最终进入页面,但是它不显示上载的文件,但可以显示名称和姓氏。如果我将此< a href = {{asset('upload /'〜element.file)}}> view< / a>
添加到我的表单中,则它给了我错误
I have set FileType $builder->add('file',FileType::class, array( 'data_class' => null, 'by_reference' => false,));
after clearing cash multiple time I can finaly enter the page but nou it does not show the uploaded file, but it does show name and lastname. If I add this <a href="{{ asset('upload/' ~ element.file) }}">view</a>
to my form then it gives me error
在呈现模板期间引发了异常(可捕获的致命错误:Symfony\Component类的对象\Form\FormView无法转换为字符串)。
An exception has been thrown during the rendering of a template ("Catchable Fatal Error: Object of class Symfony\Component\Form\FormView could not be converted to string").
因此,如果我尝试通过添加新文件进行更新,它将给我错误文件位置不存在
这可能是我的树枝出现的问题如何返回上载的文件,因为我确实使用user.id显示了上载的数据。
So if I try update by adding new file It gives me error file location does not exist
That is probably A problem with my twig How Can I return the uploaded file because I do use user.id to show the uploaded data.
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\Tests\StringableObject;
use Symfony\Component\Validator\Constraints as Assert;
//use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Files
*
* @ORM\Table(name="files")
* @ORM\Entity(repositoryClass="AppBundle\Repository\FilesRepository")
*/
class Files
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="file", type="string", length=255, unique=true)
* @Assert\NotBlank(message="Please, upload the product brochure as a PDF file.")
* @Assert\File( maxSize = "100M")
*
*/
private $file;
/**
* @var string
*
*
* @ORM\Column(name="path", type="string", length=255, nullable=true)
*/
private $path;
public function addUser(User $user)
{
if (!$this->user->contains($user)) {
$this->user->add($user);
}
}
/**
* @param $path
* @return $this
*/
public function setPath($path)
{
$this->path = $path;
return $this;
}
/**
* Get path
*
* @return string
*/
public function getPath()
{
return $this->path;
}
//
// /**
// * @ORM\ManyToMany(targetEntity="User", cascade={"persist"})
// */
// private $user;
//
// function __construct() {
// $this->user = new ArrayCollection();
// }
/**
*
* @return Files
*/
function getUser() {
return $this->user();
}
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set file
*
* @param string $file
*
* @return Files
*/
public function setFile($file)
{
$this->file = $file;
return $this;
}
/**
* Get file
*
* @return string
*/
public function getFile()
{
return $this->file;
}
/**
* @param ExecutionContextInterface $context
*/
public function validate(ExecutionContextInterface $context)
{
if (! in_array($this->file->getMimeType(), array(
'image/jpeg',
'image/gif',
'image/png',
'video/mp4',
'video/quicktime',
'video/avi',
))) {
$context
->buildViolation('Wrong file type (jpg,gif,png,mp4,mov,avi)')
->atPath('fileName')
->addViolation()
;
}
}
}
用户实体:
User entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\Tests\StringableObject;
use Symfony\Component\Validator\Constraints as Assert;
//use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Files
*
* @ORM\Table(name="files")
* @ORM\Entity(repositoryClass="AppBundle\Repository\FilesRepository")
*/
class Files
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="file", type="string", length=255, unique=true)
* @Assert\NotBlank(message="Please, upload the product brochure as a PDF file.")
* @Assert\File( maxSize = "100M")
*
*/
private $file;
/**
* @var string
*
*
* @ORM\Column(name="path", type="string", length=255, nullable=true)
*/
private $path;
public function addUser(User $user)
{
if (!$this->user->contains($user)) {
$this->user->add($user);
}
}
/**
* @param $path
* @return $this
*/
public function setPath($path)
{
$this->path = $path;
return $this;
}
/**
* Get path
*
* @return string
*/
public function getPath()
{
return $this->path;
}
//
// /**
// * @ORM\ManyToMany(targetEntity="User", cascade={"persist"})
// */
// private $user;
//
// function __construct() {
// $this->user = new ArrayCollection();
// }
/**
*
* @return Files
*/
function getUser() {
return $this->user();
}
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set file
*
* @param string $file
*
* @return Files
*/
public function setFile($file)
{
$this->file = $file;
return $this;
}
/**
* Get file
*
* @return string
*/
public function getFile()
{
return $this->file;
}
/**
* @param ExecutionContextInterface $context
*/
public function validate(ExecutionContextInterface $context)
{
if (! in_array($this->file->getMimeType(), array(
'image/jpeg',
'image/gif',
'image/png',
'video/mp4',
'video/quicktime',
'video/avi',
))) {
$context
->buildViolation('Wrong file type (jpg,gif,png,mp4,mov,avi)')
->atPath('fileName')
->addViolation()
;
}
}
}
UserType:
UserType:
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use AppBundle\Form\FilesType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
class UserType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('lastName')
->add('files', CollectionType::class,array(
'entry_type' => FilesType::class,
'allow_add' => true,
'allow_delete'=> true,
'by_reference' => false,
))
;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\User'
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_user';
}
}
FilesType:
FilesType:
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\FileType;
class FilesType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('file',FileType::class, array(
// ...
'data_class' => null,
'by_reference' => false,
));
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Files'
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_files';
}
}
UserController:
UserController:
class UserController extends Controller
{
/**
* Lists all user entities.
*
* @Route("/", name="user_index")
* @Method("GET")
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$users = $em->getRepository('AppBundle:User')->findAll();
return $this->render('user/index.html.twig', array(
'users' => $users,
));
}
/**
* @param Request $request
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
* Creates a new user entity.
*
* @Route("/new", name="user_new")
* @Method({"GET", "POST"})
*/
public function newAction(Request $request)
{
$user = new User();
$form = $this->createForm('AppBundle\Form\UserType', $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$attachments = $user->getFiles();
if ($attachments) {
foreach ($attachments as $attachment) {
$file = $attachment->getFile();
// var_dump($attachment);
$filename = md5(uniqid()) . '.' . $file->guessExtension();
$file->move(
$this->getParameter('upload_path'), $filename
);
// var_dump($filename);
$attachment->setFile($filename);
}
}
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
return $this->redirectToRoute('user_show', array('id' => $user->getId()));
}
return $this->render('user/new.html.twig', array(
'user' => $user,
'form' => $form->createView(),
));
}
/**
* Finds and displays a user entity.
*
* @Route("/{id}", name="user_show")
* @Method("GET")
*/
public function showAction(User $user)
{
$deleteForm = $this->createDeleteForm($user);
return $this->render('user/show.html.twig', array(
'user' => $user,
'delete_form' => $deleteForm->createView(),
));
}
/**
* Displays a form to edit an existing user entity.
*
* @Route("/{id}/edit", name="user_edit")
* @Method({"GET", "POST"})
*/
public function editAction(Request $request, User $user)
{
$deleteForm = $this->createDeleteForm($user);
$editForm = $this->createForm('AppBundle\Form\UserType', $user);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$attachments = $user->getFiles();
if ($attachments) {
foreach ($attachments as $attachment) {
$file = $attachment->getFile();
// var_dump($attachment);
$filename = md5(uniqid()) . '.' . $file->guessExtension();
$file->move(
$this->getParameter('upload_path'), $filename
);
// var_dump($filename);
$attachment->setFile(
new File($this->getParameter('upload_path') . '/' . $attachment->getFile())
);
}
}
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('user_edit', array('id' => $user->getId()));
}
return $this->render('user/new.html.twig', array(
'user' => $user,
'form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
/**
* Deletes a user entity.
*
* @Route("/{id}", name="user_delete")
* @Method("DELETE")
*/
public function deleteAction(Request $request, User $user)
{
$form = $this->createDeleteForm($user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->remove($user);
$em->flush();
}
return $this->redirectToRoute('user_index');
}
/**
* Creates a form to delete a user entity.
*
* @param User $user The user entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createDeleteForm(User $user)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('user_delete', array('id' => $user->getId())))
->setMethod('DELETE')
->getForm();
}
}
**Index.html.twig**
<tbody>
{% for user in users %}
<tr>
<td><a href="{{ path('user_show', { 'id': user.id }) }}">{{ user.id }}</a></td>
<td>{{ user.name }}</td>
<td>{{ user.lastName }}</td>
<td style="text-align: center; vertical-align: middle;">
<ul style="list-style-type: none;">
<li>
<a type="button" class="btn btn-info"
href="{{ path('user_show', { 'id': user.id }) }}">show</a>
</li>
<li>
<a class="btn btn-default btn-xs"
href="{{ path('user_edit', { 'id': user.id }) }}">edit</a>
</li>
</ul>
</td>
</tr>
{% endfor %}
</tbody>
**Edit.twig.html**
<div class="row-fluid">
{{ form_start(form) }}
<div class="form-group">
{{ form_row(form.name, {'attr': {'class': 'form-control'}}) }}
</div>
<div class="form-group">
{{ form_row(form.lastName, {'attr': {'class': 'form-control'}}) }}
</div>
<ul style="list-style-type: none;" class="files" data-prototype="{{ form_widget(form.files.vars.prototype)|e('html_attr') }}">
{% for element in form.files %}
<li>
{{ form_widget(element.file) }}
</li>
{% endfor %}
</ul>
<input class="btn btn-success" type="submit" value="Create"/>
{{ form_end(form) }}
<ul style="list-style-type: none;">
<li>
<a type="button" class="btn btn-primary btn-lg btn-block" href="{{ path('user_index') }}">Back to
the list</a>
</li>
</ul>
</div>
推荐答案
1 /您必须更改表格FilesType:
1/ You must change your form FilesType:
$ builder-> add('file',FileType :: class); (确保您导入了FileType类)
,并且不要忘记使用AddFile,在您实体下的removeFile方法中,by_reference为false以使其添加/删除文件
来看看文档。
$builder->add('file', FileType::class); (make sure you import FileType class) and don't forget to use AddFile, removeFile methodes under your entity with by_reference to false to make it add/delete file take a look at documentation.
2 /请注意您可以使用文件系统组件的删除函数。如果您不想使用文件系统组件,那么可以使用unlink(),在此文档的删除功能中有一个很好的例子:
公共功能removeUpload()
2/Note that you can use the remove function of the filesystem component. If you don't want to use the filesystem component, that's fine, you can use unlink(), there is a great example in this remove function of the doc: public function removeUpload()
{
if (isset($this->file)) {
unlink($this->file);
}
}
这篇关于Symfony使用原理更新和删除多个文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!