Symfony2 - 使用自定义表单类型的名称/别名调用的createForm抛出“无法加载类型”异常

时间:2013-11-24 11:49:37

标签: php forms symfony

我正在阅读有关将表单定义为服务的文档,并按照指南进行操作。但我一直遇到以下错误:

  

无法加载“提交”类型

这是我的services.yml

services:
    submission.form.type.submission:
        class:Awesome\SubmissionBundle\Form\Type\SubmissionType
        tags:
            - {name: form.type, alias: submission}

这是我的表格

<?php

namespace Awesome\SubmissionBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class SubmissionType extends AbstractType 
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('contact', 'text')
            ->add('message', 'textarea')
            ->add('submit', 'submit')
        ;
    }

    public function getName() 
    {
        return 'submission';
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    {
        $resolver->setDefaults(array(
            'data_class' => 'Awesome\SubmissionBundle\Entity\Submission',
        ));
    }
}

在任何控制器中我都可以$this->get('submission.form.type.submission')没有错误。

但为什么我不能$this->createForm('submission', $submission) ?正如官方documentation所规定的那样。

更新 我取得了一些进展。我发现,如果我将我的服务配置放在symfony的主config.yml而不是捆绑services.yml中,代码就会开始工作。这很令人困惑,但我想这会导致我发布我正在加载包services.yml的方式。

这是我的bundle的注册编译器传递:

<?php

namespace Awesome\SubmissionBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;

class SubmissionCompilerPass implements CompilerPassInterface
{

    public function process(ContainerBuilder $container)
    {
        $relative_path = DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, array('..', '..', 'Resources', 'config'));
        $loader = new YamlFileLoader($container, new FileLocator(__DIR__ . $relative_path));
        $loader->load('services.yml');
    }

}

无论我在哪里放置配置,命令container:debug submission.form.type.submission总是给出相同的输出,这对我来说似乎很好:

[container] Information for service submission.form.type.submission
Service Id       submission.form.type.submission
Class            Awesome\SubmissionBundle\Form\Type\SubmissionType
Tags
    - form.type                      (alias: submission)
Scope            container
Public           yes
Synthetic        no
Required File    -

2 个答案:

答案 0 :(得分:0)

这是另一个问题: 它是data_class,而不是data

public function setDefaultOptions(OptionsResolverInterface $resolver) 
{
    $resolver->setDefaults(array(
        'data_class' => 'Awesome\SubmissionBundle\Entity\Submission',
    ));
}

答案 1 :(得分:0)

我认为您的问题在于在CompilerPass中加载services.yml。 “form.type”标签的加载也发生在CompilerPass(Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\FormPass)中。因此,您的CompilerPass在CompilerPass表单之后执行,它将找不到您的表单类型。

如果您使用的是Symfony标准版,并且已使用generator command创建了捆绑包,那么您的DependencyInjection文件夹中将有一个AwesomeSubmissionExtension类,用于加载服务文件。

以下代码是用于加载yaml文件的已更改扩展代码。 (默认为XmlFileLoader)

namespace Awesome\SubmissionBundle\DependencyInjection;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;

class AwesomeSubmissionExtension extends Extension
{
    /**
     * {@inheritDoc}
     */
    public function load(array $configs, ContainerBuilder $container)
    {
        $configuration = new Configuration();
        $config = $this->processConfiguration($configuration, $configs);

        $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
        $loader->load('services.yml');
    }
}