编译错误:无法声明类,因为名称已被使用

dum*_*mys 3 php symfony

我正在将网站从 symfony 2.6 迁移到 3.4,但在注册表和 FOSUserBundle 方面遇到了一些问题。我有这个错误弹出。我检查了他的代码,在他的 src\Pix\UserBundle\Form\RegistrationFormType.php 下看到了另一个文件夹“Type”,其中有一个同名的文件:“RegistrationFormType.php”

我尝试用最新的样式修改表单:https : //github.com/symfony/symfony/blob/2.8/UPGRADE-2.8.md#form

应用程序/配置/config.yml:

fos_user:
    db_driver: orm
    firewall_name: main
    user_class: Pix\UserBundle\Entity\User
    registration:
        form:
            type: Pix\UserBundle\Form\RegistrationFormType
            validation_groups: [ pix_registration, Default ]
Run Code Online (Sandbox Code Playgroud)

Pix/UserBundle/Resources/config/services.yml下的服务文件

services:
    pix_userbundle_registrationformtype:
        class: Pix\UserBundle\Form\Type\RegistrationFormType
        arguments: ["%fos_user.model.user.class%"]
        tags:
            - { name: form.type }
Run Code Online (Sandbox Code Playgroud)

Pix/UserBundle/Form/RegistrationFormType.php:

fos_user:
    db_driver: orm
    firewall_name: main
    user_class: Pix\UserBundle\Entity\User
    registration:
        form:
            type: Pix\UserBundle\Form\RegistrationFormType
            validation_groups: [ pix_registration, Default ]
Run Code Online (Sandbox Code Playgroud)

最后是 Pix/UserBundle/Form/Type/RegistrationFormType.php:

services:
    pix_userbundle_registrationformtype:
        class: Pix\UserBundle\Form\Type\RegistrationFormType
        arguments: ["%fos_user.model.user.class%"]
        tags:
            - { name: form.type }
Run Code Online (Sandbox Code Playgroud)

Ger*_*ser 8

如果类中定义的命名空间与类 php 文件的路径不匹配,则可能会发生此错误。解决命名空间也将解决此错误。


小智 7

由于 services.yml 文件中的配置错误,我遇到了此错误:

App\:
    resource: '../src/*'
    exclude: '../src/{Entity,Migrations,Tests,Kernel.php}'

Example\:
    resource: '../src/Example/*'
    public: true
Run Code Online (Sandbox Code Playgroud)

这将导致 Symfony 尝试加载 Example 命名空间下的类 App\Example

您需要确保将任何自定义命名空间添加到应用程序的排除列表中,如下所示:

App\:
    resource: '../src/*'
    exclude: '../src/{Entity,Migrations,Tests,Kernel.php,Example}'
Run Code Online (Sandbox Code Playgroud)


Art*_*nix 5

这主要是由于您的 import 或 use 语句与您定义的类同名:

use FOS\UserBundle\Form\Type\RegistrationFormType;

class RegistrationFormType extends AbstractType
{
Run Code Online (Sandbox Code Playgroud)

例如拿这个代码:

namespace foo{

    class class1{

    }

}
namespace bar{
    //use foo\class1;

    class class1{

    }
}
Run Code Online (Sandbox Code Playgroud)

沙盒

这工作正常并且不会产生错误(正如预期的那样),但是如果您取消注释此行:

use foo\class1;
Run Code Online (Sandbox Code Playgroud)

输出

<br />
<b>Fatal error</b>:  Cannot declare class bar\class1 because the name is already in use in <b>[...][...]</b> on line <b>14</b><br />
Run Code Online (Sandbox Code Playgroud)

沙盒

我们应该同意上面的例子大致等同于你正在做的事情(它是)。

所以基本上发生的事情是你定义这个使用语句:

use FOS\UserBundle\Form\Type\RegistrationFormType; 
Run Code Online (Sandbox Code Playgroud)

这允许您在RegistrationFormType没有名称空间的情况下使用此类,但由于您还定义了相同的类名,因此会出现错误(请参阅下面的歧义)。

你可以给它起别名,像这样:

 use FOS\UserBundle\Form\Type\RegistrationFormType as FOSRegistrationFormType;
Run Code Online (Sandbox Code Playgroud)

然后,当您需要该命名空间中的某些内容时,您只需使用FOSRegistrationFormType. 也就是说,您使用它的唯一地方(也许)是这种方法:

public function getParent()
{
    return RegistrationFormType::class;
}
Run Code Online (Sandbox Code Playgroud)

我说“也许”是因为它的方式是模棱两可的。我不知道您是否想要命名的当前对象的类,RegistrationFormType或者您是否想要FOS\UserBundle\Form\Type\RegistrationFormType::class. PHP 也不知道这一点。如果它是对象的类,那么只需执行__CLASS__并删除该use语句。如果它是另一个(或者你在我看不到的地方需要那个类),那么只需将它作为别名并执行FOSRegistrationFormType::class.

我同意这个错误信息可能会更好,它应该是类名的使用RegistrationFormType不明确等。但事实并非如此,所以我们必须处理它......这个问题让我绊倒了几次,这就是为什么我基本上立即意识到了这一点。

我将分享对我的简单沙箱代码的最后修改:

namespace foo{

    class class1{

    }

}
namespace bar{
    use foo\class1 as f;

    class class1{
        public function test(){
            echo f::class;
        }
    }

    (new class1)->test();
}
Run Code Online (Sandbox Code Playgroud)

输出

 foo\class1
Run Code Online (Sandbox Code Playgroud)

沙盒

显然,使用一个更冗长的别名,f但是,这显示了如何为它设置别名,然后从别名中获取类,类似于您的代码所做的。

PS虽然它很丑,但如果你只使用它一次,没有理由你不能只使用完全限定名称(命名空间/类),只要确保有一个前导\(想想相对路径工作)如:

  \FOS\UserBundle\Form\Type\RegistrationFormType::class
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你。