使用 Symfony3 组件时,Silex FormServiceProvider 无法加载类型 "form"

Silex FormServiceProvider could not load type "form" when using Symfony3 Components

尝试构建表单时收到此错误:

InvalidArgumentException in FormRegistry.php line 87: Could not load type "form"

我已经注册了 FormServiceProvider、TranslationServicerProvider 和 ValidatorServiceProvider。

这是我的代码的相关部分:

        $this->_form = $this->_app['form.factory']->createBuilder('form', $this->_map())
        ->add('firstName', 'text', [
            'constraints' => [new Assert\NotBlank()]
        ])
        ->add('lastName', 'text', [
            'constraints' => [new Assert\NotBlank()]
        ])
        ->add('email', 'text', [
            'constraints' => [new Assert\Email()]
        ])
        ->getForm();

以下是我正在使用的相关组件的版本号:

silex/silex v1.3.4 The PHP micro-framework based on the Symfony Components symfony/security-core
v3.0.1 Symfony Security Component - Core Library symfony/security-csrf v3.0.1 Symfony Security Component - CSRF Library symfony/translation v3.0.1 Symfony Translation Component symfony/twig-bridge v3.0.1 Symfony Twig Bridge symfony/validator v3.0.1 Symfony Validator Component symfony/form v3.0.1

我在以前的 Silex 版本中能够成功地做到这一点;是什么东西坏了还是我遗漏了什么?

Silex 的最新版本似乎不适用于 Symfony Forms v3。 要使其工作,请将您的作曲家文件中的要求替换为:

{
    "require": {
        "silex/silex": "^1.3",
        "symfony/form": "~2.3",
        "symfony/security-csrf": "~2.3"
    }
}

将 Symfony 组件降级到版本 2.8.1 解决了这个问题;这显然是 Silex 和 Symfony3 之间的 backward-compatibility 问题。

您实际上可以将 Symfony Form 3 与 Silex 一起使用,但 createBuilder 函数现在要求您遵守将类型作为参数传递的新方法。 Silex 文档尚未更新以反映这一点。

在 2.8 之前,类型通常作为字符串传入,例如 'form'、'text'、'email' 等等,Symfony 组件将其解析为正确的 class.现在你必须传入一个 classname 来代替。

所以,以前的 form 现在变成了 Symfony\Component\Form\Extension\Core\Type\FormType::classtext 变为 Symfony\Component\Form\Extension\Core\Type\TextType::class。当然,您可以导入这些 classes 这样就不必使用完整的命名空间。

可以使用以下代码修复此线程中发布的特定问题:

use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;

$this->_form = $this->_app['form.factory']
    ->createBuilder(FormType::class, $this->_map())
    ->add(
        'firstName', 
        TextType::class, [
            'constraints' => [new Assert\NotBlank()]
        ]
    )
    ->add(
        'lastName', 
        TextType::class, [
             'constraints' => [new Assert\NotBlank()]
        ]
     )
    ->add(
         'email', 
         EmailType::class, [
              'constraints' => [new Assert\Email()]
         ]
    )
    ->getForm();

请参考official documentation.

P.S:这是对 here 的讨论的总结。我已经测试过这有效。