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

时间:2019-04-01 21:51:31

标签: php forms symfony fosuserbundle

免责声明:我正在帮助一个朋友,因为他的网站管理员离开了他,我不是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

app / config / 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 ]

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 }

Pix / UserBundle / Form / RegistrationFormType.php:

namespace Pix\UserBundle\Form;

use FOS\UserBundle\Form\Type\RegistrationFormType as BaseRegistrationFormType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;


class RegistrationFormType extends AbstractType
{

    public function __construct($class = "User")
    {
        parent::__construct($class);
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        parent::buildForm($builder, $options);

        $builder
            ->add('username', 'text', array(
                'label' => 'Pseudonyme',
            ))
            ->add('email', 'text', array(
                'label' => 'Adresse mail',
            ))
            ->add('plainPassword', 'repeated', array(
                'type' => 'password',
                'first_options' => array('label' => 'Mot de passe'),
                'second_options' => array('label' => 'Confirmation'),
                'invalid_message' => 'Mot de passe incorrect',
            ))
            ->add('enabled', 'checkbox', array(
                'label' => "Activé",
                'required' => false
            ))

            ->add('firstname', 'text', array(
                'label' => 'Prénom',
            ))
            ->add('lastname', 'text', array(
                'label' => 'Nom',
            ))
            ->add('phone', 'text', array(
                'label' => 'Téléphone',
            ))
            ->add('street', 'text', array(
                'label' => "Adresse postale",
                'required' => true
            ))
            ->add('number', 'text', array(
                'label' => "Numéro d'adresse",
                'required' => true
            ))
            ->add('npa', 'text', array(
                'label' => "Code postal",
                'required' => true
            ))
            ->add('city', 'text', array(
                'label' => "Ville",
                'required' => true
            ))
            ->add('state', 'text', array(
                'label' => "Canton",
                'required' => true
            ))
            ->add('country', 'text', array(
                'label' => "Pays",
                'required' => true
            ))
            ->add('latitude', 'text', array(
                'label' => "Latitude",
                'required' => true
            ))
            ->add('longitude', 'text', array(
                'label' => "Longitude",
                'required' => true
            ))
            ->add('code', 'text', array(
                'label' => 'Code de parrainage',
                'required' => false
            ))
            ->add('pro', 'choice', array(
                'label' => "Professionel",
                'choices'  => array(
                    true => 'Oui',
                    false => 'Non',
                ),
                'expanded' => false,
                'multiple' => false,
                'required' => true
            ))

            ->add('iban', 'text', array(
                'label' => 'IBAN',
                'required' => false
            ))
            ->add('distance', 'text', array(
                'label' => "Rayon d'intervention",
                'required' => false
            ))
            ->add('picture', new DocumentType(), array('required' => false))
            ->add('curriculum', new DocumentType(), array('required' => false))
            ->add('motivation', new DocumentType(), array('required' => false))
            ->add('document', new DocumentType(), array('required' => false))
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Pix\UserBundle\Entity\User'
        ));
    }
    public function getParent()
    {
        return BaseRegistrationFormType::class;
    }
    public function getBlockPrefix()
    {
        return 'pix_userbundle_registrationformtype';
    }
}

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

namespace Pix\UserBundle\Form\Type;

use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use FOS\UserBundle\Form\Type\RegistrationFormType;
use Symfony\Component\Form\AbstractType;
use Pix\UserBundle\Form\DocumentType;
use Pix\UserBundle\Entity\AbilityRepository;
use Symfony\Component\Form\Extension\Core\Type\TextType; 

class RegistrationFormType extends AbstractType
{

    public function __construct($class = "User")
    {
        parent::__construct($class);
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        parent::buildForm($builder, $options);
        $builder->remove('username');
        $builder
            ->add('firstname', TexType::class, array(
                'label' => 'Prénom',
            ))
            ->add('lastname', TexType::class, array(
                'label' => 'Nom',
            ))
            ->add('phone', TexType::class, array(
                'label' => 'Téléphone',
            ))
            ->add('street', 'hidden')
            ->add('number', 'hidden')
            ->add('npa', 'hidden')
            ->add('city', 'hidden')
            ->add('state', 'hidden')
            ->add('country', 'hidden')
            ->add('latitude', 'hidden')
            ->add('longitude', 'hidden')
            ->add('code', TexType::class, array(
                'label' => 'Code de parrainage',
                'required' => false
            ))
            /*
            ->add('contact', 'choice', array(
                'label' => 'Moyen de contact favorisé',
                'choices'  => array(
                    true => 'Par téléphone',
                    false => 'Par e-mail',
                ),
                'expanded' => true,
                'multiple' => false,
                'required' => true
            ))
            */
            ->add('pro', 'choice', array(
                'label' => false,
                'choices'  => array(
                    true => 'Oui',
                    false => 'Non',
                ),
                'expanded' => false,
                'multiple' => false,
                'required' => true
            ))

            ->add('iban', TexType::class, array(
                'label' => 'IBAN',
                'required' => false
            ))
            ->add('distance', TexType::class, array(
                'label' => "Rayon d'intervention",
                'required' => false
            ))
            ->add('picture', new DocumentType(), array('required' => false))
            ->add('curriculum', new DocumentType(), array('required' => false))
            ->add('motivation', new DocumentType(), array('required' => false))
            ->add('document', new DocumentType(), array('required' => false))

            ->add('abilities', 'entity', array(
                'label' => 'Domaines de compétence',
                'attr' => array(
                    'class'=>'form-control multiselect'
                ),
                'class' => 'PixUserBundle:Ability',
                'property' => 'title',
                'multiple' => true,
                'expanded' => true,
                'required' => false,
                'query_builder' => function(AbilityRepository $er) {
                    return $er->getAbilities();
                },
            ))
            ->add('condition', 'checkbox', array('label' => "J'ai lu et j'accepte les conditions générales."))
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Pix\UserBundle\Entity\User',
            'intention'  => 'registration'
        ));
    }
    public function getBlockPrefix()
    {
        return 'pix_userbundle_registrationformtype';
    }
    public function getParent()
    {
    return RegistrationFormType::class;
    }
}

有很多代码,但是我认为需要了解我的问题。谢谢你帮我 乔恩

3 个答案:

答案 0 :(得分:2)

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

use FOS\UserBundle\Form\Type\RegistrationFormType;

class RegistrationFormType extends AbstractType
{

例如,使用以下代码:

namespace foo{

    class class1{

    }

}
namespace bar{
    //use foo\class1;

    class class1{

    }
}

Sandbox

这可以正常工作,并且不会产生任何错误(按预期),但是,如果您取消注释此行:

use foo\class1;

输出

<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 />

Sandbox

我们应该同意,上面的示例与您正在做的事情大致相同。

基本上,您定义的使用状态是怎么回事:

use FOS\UserBundle\Form\Type\RegistrationFormType; 

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

您可以像这样对它起别名:

 use FOS\UserBundle\Form\Type\RegistrationFormType as FOSRegistrationFormType;

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

public function getParent()
{
    return RegistrationFormType::class;
}

我之所以说“也许”,是因为它是模棱两可的。我不知道您是否要使用名为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();
}

输出

 foo\class1

Sandbox

显然,使用比f更详细的别名,但是,这说明了如何对它进行别名,然后从别名中获取类,类似于您的代码。

PS 虽然很丑陋,但如果只使用一次,则没有理由不能只使用完全限定名称(命名空间/类),只需确保是领先的\(想想相对路径是如何工作的),如下所示:

  \FOS\UserBundle\Form\Type\RegistrationFormType::class

希望有帮助。

答案 1 :(得分:2)

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

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

Example\:
    resource: '../src/Example/*'
    public: true

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

您还需要确保将所有自定义名称空间也添加到App的排除列表中,如下所示:

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

答案 2 :(得分:0)

我在为实体形成 Doctrine 缓存时遇到了名称冲突。

在这种情况下出现冲突(说明性示例):

class AlphaBeta {}

为其生成缓存文件:__CG__AlphaBeta.php

namespace Alpha;

class Beta {}

还为它生成了一个缓存文件:__CG__AlphaBeta.php,并且得到了名字冲突!那些。只存储了一个类的缓存,这会引发错误!

附言实体文件缓存的路径是这样的:./var/cache/prod/doctrine/orm/Proxies