我正在尝试更新(多个)上传的文件
我有两个问题。当我尝试从索引输入编辑表单时.html树枝会给我以下错误:
表单的视图数据应该是类 Symfony\Component\HttpFoundation\File\File 的实例,但是一个 (n) 字符串。您可以通过将"data_class"选项设置为 null 或添加将 (n) 字符串转换为 Symfony\Component\HttpFoundation\File\File 实例的视图转换器来避免此错误。
我试图data_class选项设置为 null,但它给出了另一个错误,它不起作用。
所以不是当我尝试更新时,而是当我尝试转到编辑表单时。我已经尝试了有关堆栈溢出的其他问题的多种解决方案,但不断收到此错误。
第二个问题是在我尝试删除文件的那一刻,它只从数据库中删除而不是文件。我知道删除时我没有引用文件的位置。我不知道该怎么做。我看过一些Symfony 2的例子,但当我尝试时它不起作用。有人可以帮助我解决这些问题吗?
编辑
我已经设置了文件类型$builder->add('file',FileType::class, array( 'data_class' => null, 'by_reference' => false,));
多次清算现金后,我可以最终进入页面,但不显示上传的文件,但它确实显示姓名和姓氏。如果我将此<a href="{{ asset('upload/' ~ element.file) }}">view</a>
添加到我的表单中,那么它会给我错误
在呈现模板期间抛出异常("可捕获的致命错误:类 Symfony\Component\Form\FormView 的对象无法转换为字符串")。
因此,如果我尝试通过添加新文件进行更新,它会给我错误file location does not exist
这可能是我的树枝有问题 如何返回上传的文件,因为我确实使用 user.id 来显示上传的数据。
文件实体:
<?php
namespace AppBundleEntity;
use DoctrineORMMapping as ORM;
use SymfonyComponentHttpFoundationTestsStringableObject;
use SymfonyComponentValidatorConstraints as Assert;
//use VichUploaderBundleMappingAnnotation as Vich;
use SymfonyComponentHttpFoundationFileFile;
use SymfonyComponentHttpFoundationFileUploadedFile;
use SymfonyComponentValidatorContextExecutionContextInterface;
use DoctrineCommonCollectionsArrayCollection;
/**
* Files
*
* @ORMTable(name="files")
* @ORMEntity(repositoryClass="AppBundleRepositoryFilesRepository")
*/
class Files
{
/**
* @var int
*
* @ORMColumn(name="id", type="integer")
* @ORMId
* @ORMGeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORMColumn(name="file", type="string", length=255, unique=true)
* @AssertNotBlank(message="Please, upload the product brochure as a PDF file.")
* @AssertFile( maxSize = "100M")
*
*/
private $file;
/**
* @var string
*
*
* @ORMColumn(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;
}
//
// /**
// * @ORMManyToMany(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()
;
}
}
}
用户实体:
<?php
namespace AppBundleEntity;
use DoctrineORMMapping as ORM;
use SymfonyComponentHttpFoundationTestsStringableObject;
use SymfonyComponentValidatorConstraints as Assert;
//use VichUploaderBundleMappingAnnotation as Vich;
use SymfonyComponentHttpFoundationFileFile;
use SymfonyComponentHttpFoundationFileUploadedFile;
use SymfonyComponentValidatorContextExecutionContextInterface;
use DoctrineCommonCollectionsArrayCollection;
/**
* Files
*
* @ORMTable(name="files")
* @ORMEntity(repositoryClass="AppBundleRepositoryFilesRepository")
*/
class Files
{
/**
* @var int
*
* @ORMColumn(name="id", type="integer")
* @ORMId
* @ORMGeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORMColumn(name="file", type="string", length=255, unique=true)
* @AssertNotBlank(message="Please, upload the product brochure as a PDF file.")
* @AssertFile( maxSize = "100M")
*
*/
private $file;
/**
* @var string
*
*
* @ORMColumn(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;
}
//
// /**
// * @ORMManyToMany(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()
;
}
}
}
用户类型:
<?php
namespace AppBundleForm;
use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentOptionsResolverOptionsResolver;
use AppBundleFormFilesType;
use SymfonyComponentFormExtensionCoreTypeCollectionType;
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' => 'AppBundleEntityUser'
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_user';
}
}
文件类型:
namespace AppBundleForm;
use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentOptionsResolverOptionsResolver;
use SymfonyComponentFormExtensionCoreTypeFileType;
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' => 'AppBundleEntityFiles'
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_files';
}
}
用户控制器:
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 SymfonyComponentHttpFoundationRedirectResponse|SymfonyComponentHttpFoundationResponse
* Creates a new user entity.
*
* @Route("/new", name="user_new")
* @Method({"GET", "POST"})
*/
public function newAction(Request $request)
{
$user = new User();
$form = $this->createForm('AppBundleFormUserType', $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('AppBundleFormUserType', $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 SymfonyComponentFormForm 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/您必须更改表单 文件类型:
$builder->add('file', FileType::class);(确保导入文件类型类) 并且不要忘记使用AddFile,删除实体下的File方法,by_reference为false以使其添加/删除文件 查看文档。
2/请注意,您可以使用文件系统组件的删除功能。如果你不想使用文件系统组件,没关系,你可以使用 unlink(),在文档的这个删除函数中有一个很好的例子: 公共函数 removeUpload()
{
if (isset($this->file)) {
unlink($this->file);
}
}