Twig 无法加载类型“;文件";在Symfony3中
我正在建立多个图像上传的形式,我无法找到解决问题的方法,在标题中提到。为了帮助我,我包括 现在我被这个错误所困扰,我无法找到代码中错误的原因和位置:Twig 无法加载类型“;文件";在Symfony3中,twig,symfony,symfony-forms,vichuploaderbundle,Twig,Symfony,Symfony Forms,Vichuploaderbundle,我正在建立多个图像上传的形式,我无法找到解决问题的方法,在标题中提到。为了帮助我,我包括 现在我被这个错误所困扰,我无法找到代码中错误的原因和位置: Could not load type "file" 500 Internal Server Error - InvalidArgumentException 有人知道问题出在哪里吗 以下是我正在使用的代码: ProductType类别: <?php namespace AppBundle\Form\Type; use Symfony\
Could not load type "file"
500 Internal Server Error - InvalidArgumentException
有人知道问题出在哪里吗
以下是我正在使用的代码:
ProductType类别:
<?php
namespace AppBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Vich\UploaderBundle\Form\Type\VichFileType;
use AppBundle\Entity\Product;
class ProductType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', TextType::class)
->add('content', TextType::class)
->add('price', TextType::class)
->add('categories')
->add('productCondition')
->add("images", CollectionType::class, array(
'entry_type' => ProductImageType::class,
'allow_add' => true,
'allow_delete' => true
)
);
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Product::class
));
}
}
编辑:
我从ProductImageType中删除了“文件”,错误消失了,但Twig无法呈现表单。此外,我还尝试使用self::class而不是“file”,这也没有帮助
//ProductImageType class
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('image')
;
}
细枝模板中的结果:
<div class="form-group">
<label class="control-label required">Images</label>
<div id="product_images" data-prototype="<div class="form-group"><label class="control-label required">__name__label__</label><div id="product_images___name__"><div class="form-group"><label class="control-label required" for="product_images___name___image">Image</label><input type="text" id="product_images___name___image" name="product[images][__name__][image]" required="required" class="form-control" /></div></div></div>"></div>
</div>
图像
编辑2:添加了细枝形式
{% extends 'AppBundle::layout.html.twig' %}
{% block stylesheets %}
{{ parent() }}
<link href="{{ asset('/assets/vendor/components-font-awesome/css/font-awesome.min.css') }}" rel="stylesheet">
<link href="{{ asset('assets/css/form-elements.css') }}" rel="stylesheet">
<link href="{{ asset('assets/css/forms.css') }}" rel="stylesheet">
{% endblock %}
{% block content %}
<div class="top-content">
<div class="inner-bg">
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="form-box">
<div class="form-top">
<div class="form-top-left">
<h3>Create new product condition!</h3>
</div>
<div class="form-top-right">
<i class="fa fa-plus"></i>
</div>
</div>
<div class="form-bottom">
{{ form_start(form, { 'attr': {'class': 'product-form'} }) }}
{% spaceless %}
{% if not form.vars.valid %}
<div class="alert alert-error">
{{ form_errors(form) }}
{% for children in form.children %}
{% if not children.vars.valid %}
{{ form_errors(children) }}
{# or with field label
<ul>
{% for error in children.vars.errors %}
<li><b>{{ children.vars.label }}</b>: {{ error.message }}</li>
{% endfor %}
</ul>
#}
{% endif %}
{% endfor %}
</div>
{% endif %}
{% endspaceless %}
{{ form_row(form.title) }}
{{ form_row(form.content) }}
{{ form_row(form.price) }}
{{ form_row(form.categories) }}
{{ form_row(form.productCondition) }}
{{ form_row(form.images) }}
<button type="submit" class="btn">Submit!</button>
{{ form_end(form) }}
</div>
</div>
</div>
</div>
{% endblock content %}
{%extends'AppBundle::layout.html.twig%}
{%块样式表%}
{{parent()}}
{%endblock%}
{%block content%}
创造新的产品条件!
{{form_start(form,{'attr':{'class':'product form'}}}}
{%spaceless%}
{%如果不是form.vars.valid%}
{{form_errors(form)}}
{%为form.children%}
{%如果不是children.vars.valid%}
{{form_errors(children)}
{#或具有字段标签
{%for children.vars.errors%中的错误}
- {{children.vars.label}}:{{error.message}
{%endfor%}
#}
{%endif%}
{%endfor%}
{%endif%}
{%endspaceless%}
{{form_row(form.title)}
{{form_row(form.content)}
{{form_row(form.price)}}
{{form_row(form.categories)}
{{form_row(form.productCondition)}
{{form_row(form.images)}
提交
{{form_end(form)}}
{%endblock内容%}
以下是您应该如何将其添加到表单中:
use Symfony\Component\Form\Extension\Core\Type\FileType;
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('image', FileType::class);
}
在Symfony 3中,表单类型总是通过其完全限定的类名传递,下面是您应该如何将其添加到表单中:
use Symfony\Component\Form\Extension\Core\Type\FileType;
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('image', FileType::class);
}
在Symfony 3中,表单类型总是通过其完全限定的类名传递,正如我所承诺的,我将向您提供一个小示例,说明如何创建多个上载表单&如何从表单获取数据,并将其从临时目录移动到所需的目录,以及在数据库中保存路径 1) 创建实体类
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table(name="galleries")
* @ORM\Entity(repositoryClass="AppBundle\Repository\GalleryRepository")
*/
class Gallery
{
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(name="path", type="string", length=255)
*/
private $path;
// getter for $id, setter & getter for $path here
}
3) 上传将使用上传服务完成,如所述。因此,设置希望文件进入config.yml
的目录(不要在parameters.yml
中设置此参数,因为如果推送项目,git会忽略此文件)
4) 声明服务
#app/config/services.yml
services:
app.img_upload:
class: AppBundle\Services\FileUpload
arguments: ['%upload_dir%']
#AppBundle\Services\FileUpload.php
namespace AppBundle\Services;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class FileUpload
{
private $targetDir;
public function __construct($targetDir)
{
$this->targetDir = $targetDir;
}
public function upload(UploadedFile $file)
{
$file_name = $file->getClientOriginalName();
empty($file_name) ? $file_name = md5(uniqid()).'.'.$file->guessExtension() : $file_name = $file->getClientOriginalName();
$file->move($this->targetDir, $file_name);
return $file_name;
}
}
5) 创建服务
#app/config/services.yml
services:
app.img_upload:
class: AppBundle\Services\FileUpload
arguments: ['%upload_dir%']
#AppBundle\Services\FileUpload.php
namespace AppBundle\Services;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class FileUpload
{
private $targetDir;
public function __construct($targetDir)
{
$this->targetDir = $targetDir;
}
public function upload(UploadedFile $file)
{
$file_name = $file->getClientOriginalName();
empty($file_name) ? $file_name = md5(uniqid()).'.'.$file->guessExtension() : $file_name = $file->getClientOriginalName();
$file->move($this->targetDir, $file_name);
return $file_name;
}
}
6) 在控制器中创建整个逻辑
#AppBundle/Controller/DefaultController.php
namespace AppBundle\Controller;
//...
use AppBundle\Entity\Gallery;
use AppBundle\Form\GalleryType;
//class...
/**
* @Route("/", name="homepage")
*/
public function indexAction(Request $request)
{
$gallery = new Gallery();
$form = $this->createForm(GalleryType::class, $gallery, [
'action'=>$this->generateUrl('homepage'),
'method'=>'POST'
]);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
$paths = $form->get('path')->getData();
foreach ($paths as $path){
$img = $this->get('app.img_upload')->upload($path);
$em = $this->getDoctrine()->getConnection();
$stmt = $em->prepare('INSERT INTO galleries SET path=?');
$stmt->execute([$img]);
// THIS IS THE PROBLEM I ENCOUNTER! I COULDN'T USE NORMAL DOCTRINE WAY TO SAVE EACH IMAGE PATH INTO THE DB. KNOW THE FIX? POST IT HERE PLEASE!
// $em = $this->getDoctrine()->getManager();
// $em->persist($gallery);
// $em->flush();
//LE: I've found the "bug": you need to instantiate, for each $path, a new $gallery object, then set the data for it, + persist & flush.
}
$this->addFlash('success', 'The image(s) were successfully uploaded');
return $this->redirectToRoute('homepage');
}
return $this->render('default/index.html.twig', ['form'=>$form->createView()]);
}
7) 最后,显示表单
# app/Resource/views/default/index.html.twig
{% extends 'base.html.twig' %}
{% block body %}
{{ form_start(form) }}
{{ form_row(form.path) }}
<button type="submit" title="Upload an image">
Upload
</button>
{{ form_end(form) }}
{% endblock %}
#app/Resource/views/default/index.html.twig
{%extends'base.html.twig%}
{%block body%}
{{form_start(form)}}
{{form_行(form.path)}
上载
{{form_end(form)}}
{%endblock%}
正如我所承诺的,我将向您提供一个小示例,说明如何创建一个多上传表单&如何从表单中获取数据,并将其从临时目录移动到所需目录,并将路径保存在数据库中
1) 创建实体类
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table(name="galleries")
* @ORM\Entity(repositoryClass="AppBundle\Repository\GalleryRepository")
*/
class Gallery
{
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(name="path", type="string", length=255)
*/
private $path;
// getter for $id, setter & getter for $path here
}
3) 上传将使用上传服务完成,如所述。因此,设置希望文件进入config.yml
的目录(不要在parameters.yml
中设置此参数,因为如果推送项目,git会忽略此文件)
4) 声明服务
#app/config/services.yml
services:
app.img_upload:
class: AppBundle\Services\FileUpload
arguments: ['%upload_dir%']
#AppBundle\Services\FileUpload.php
namespace AppBundle\Services;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class FileUpload
{
private $targetDir;
public function __construct($targetDir)
{
$this->targetDir = $targetDir;
}
public function upload(UploadedFile $file)
{
$file_name = $file->getClientOriginalName();
empty($file_name) ? $file_name = md5(uniqid()).'.'.$file->guessExtension() : $file_name = $file->getClientOriginalName();
$file->move($this->targetDir, $file_name);
return $file_name;
}
}
5) 创建服务
#app/config/services.yml
services:
app.img_upload:
class: AppBundle\Services\FileUpload
arguments: ['%upload_dir%']
#AppBundle\Services\FileUpload.php
namespace AppBundle\Services;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class FileUpload
{
private $targetDir;
public function __construct($targetDir)
{
$this->targetDir = $targetDir;
}
public function upload(UploadedFile $file)
{
$file_name = $file->getClientOriginalName();
empty($file_name) ? $file_name = md5(uniqid()).'.'.$file->guessExtension() : $file_name = $file->getClientOriginalName();
$file->move($this->targetDir, $file_name);
return $file_name;
}
}
6) 在控制器中创建整个逻辑
#AppBundle/Controller/DefaultController.php
namespace AppBundle\Controller;
//...
use AppBundle\Entity\Gallery;
use AppBundle\Form\GalleryType;
//class...
/**
* @Route("/", name="homepage")
*/
public function indexAction(Request $request)
{
$gallery = new Gallery();
$form = $this->createForm(GalleryType::class, $gallery, [
'action'=>$this->generateUrl('homepage'),
'method'=>'POST'
]);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
$paths = $form->get('path')->getData();
foreach ($paths as $path){
$img = $this->get('app.img_upload')->upload($path);
$em = $this->getDoctrine()->getConnection();
$stmt = $em->prepare('INSERT INTO galleries SET path=?');
$stmt->execute([$img]);
// THIS IS THE PROBLEM I ENCOUNTER! I COULDN'T USE NORMAL DOCTRINE WAY TO SAVE EACH IMAGE PATH INTO THE DB. KNOW THE FIX? POST IT HERE PLEASE!
// $em = $this->getDoctrine()->getManager();
// $em->persist($gallery);
// $em->flush();
//LE: I've found the "bug": you need to instantiate, for each $path, a new $gallery object, then set the data for it, + persist & flush.
}
$this->addFlash('success', 'The image(s) were successfully uploaded');
return $this->redirectToRoute('homepage');
}
return $this->render('default/index.html.twig', ['form'=>$form->createView()]);
}
7) 最后,显示表单
# app/Resource/views/default/index.html.twig
{% extends 'base.html.twig' %}
{% block body %}
{{ form_start(form) }}
{{ form_row(form.path) }}
<button type="submit" title="Upload an image">
Upload
</button>
{{ form_end(form) }}
{% endblock %}
#app/Resource/views/default/index.html.twig
{%extends'base.html.twig%}
{%block body%}
{{form_start(form)}}
{{form_行(form.path)}
上载
{{form_end(form)}}
{%endblock%}
@Veve在ProductImageType类中?@Veve我试过了,现在我的表单是空的。它甚至不会渲染。我也尝试过使用self::class,但它仍然不适用于Symfony 3,Symfony 3是在ProductImageType.php
中添加的字段,我想它应该是FileType
类型(需要导入),而且不是文件类型
@DanCostinel我尝试了你的建议,我得到的结果与我在编辑后的段落中包含的结果相同。VichUploaderBundle
bundle是你的项目的要求吗?如果没有,我可以为您提供一个多上传功能代码的示例。@Veve在ProductImageType类中?@Veve我试过了,现在我的表单是空的。它甚至不会渲染。我也尝试过使用self::class,但它仍然不适用于Symfony 3,Symfony 3是在ProductImageType.php
中添加的字段,我想它应该是FileType
类型(需要导入),而且不是文件类型
@DanCostinel我尝试了你的建议,我得到的结果与我在编辑后的段落中包含的结果相同。VichUploaderBundle
bundle是你的项目的要求吗?如果没有,我可以提供一个多上传功能代码的例子。我试过了,但是我在Twig模板中遇到了一个有线问题。你可以在编辑段落下检查twig的结果,模板是什么?它是bootstrap_3_layout.html。twig表单模板文件类型应该以div中的类型文件呈现输入,仅此而已。这段html从何而来?我用twig文件编辑了我的帖子。我不知道为什么我会得到这个html代码。有没有