Ошибка компиляции: невозможно объявить класс, так как имя уже используется - PullRequest
1 голос
/ 02 апреля 2019

отказ от ответственности: я помогаю другу, потому что его веб-мастер оставил его, я не лучший парень в php / symfony.

Я перевожу сайт с symfony 2.6 на 3.4, и у меня есть некоторыеПроблемы с регистрационными формами и FOSUserBundle.У меня эта ошибка выскакивает.Я проверил его код и увидел, что в его src \ Pix \ UserBundle \ Form \ RegistrationFormType.php есть еще одна папка «Тип» с файлом с таким же именем: «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;
    }
}

Там много кода, но я думаю, что это необходимо, чтобы понять мою проблему.Спасибо за помощь.Jon

1 Ответ

2 голосов
/ 02 апреля 2019

Это связано с тем, что ваш оператор импорта или использования имеет то же имя, что и класс, который вы определяете:

use FOS\UserBundle\Form\Type\RegistrationFormType;

class RegistrationFormType extends AbstractType
{

Например, возьмите этот код:

namespace foo{

    class class1{

    }

}
namespace bar{
    //use foo\class1;

    class class1{

    }
}

Песочница

Это работает нормально и не выдает ошибок (как и ожидалось), однако, если вы раскомментируете эту строку:

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

Песочница

Мы должны согласиться, что приведенный выше пример примерно эквивалентен тому, что вы делаете (что это такое).

Итак, в основном вы определяете это использование statemnt:

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

Песочница

Очевидно, что используется псевдоним, который является более многословным, чем f, но это показывает, как вы можете создать псевдоним и затем получить класс из псевдонима, аналогично тому, что делает ваш код.

PS Хотя это уродливо, но если вы используете его только один раз, нет причины, по которой вы не можете просто использовать для этого полностью определенное имя (пространство имен / класс), просто убедитесь, что оно есть. ведущий \ (подумайте об этом, как работают относительные пути) как в:

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

Надеюсь, это поможет.

...