将新用户持久保存到数据库

时间:2014-11-12 13:59:05

标签: php symfony doctrine

我知道FOSuserbundle的可用性,但是为了帮助学习symfony2,我决定尝试使用book / cookbook从头开始创建所有内容。

在遵循cookbooks安全性教程后,我无法确定如何将新用户持久保存到数据库中。我还有其他一切正常,登录,防火墙安全域,密码加密等

当我尝试添加用户时,我收到以下错误:

  

属性"角色"也没有其中一种方法" addRol()" /" removeRol()"," addRole()" /" removeRole()&# 34;," setRoles()"," roles()"," __ set()"或" __ call()"在课堂上存在并拥有公共访问权限" Ampisoft \ Bundle \ etrackBundle \ Entity \ users"

我注意到users()类没有setRoles方法,但我不确定如何添加一个,因为它需要使用数组对象(?)。令我困惑的另一件事是错误突出显示没有addRole()(而不是addRoles方法,即使该成员是roles

我的代码如下:

用户实体类(它非常有用,所以这些只是我认为重要的部分

class users implements AdvancedUserInterface, \Serializable
{
    // ......

    /**
     * @ORM\ManyToMany(targetEntity="roles", inversedBy="users")
     *
     */
    private $roles;


    /**
     * @inheritDoc
     */
    public function getRoles()
    {
        return $this->roles->toArray();
    }

   /**
     * Add roles
     *
     * @param \Ampisoft\Bundle\etrackBundle\Entity\roles $roles
     * @return users
     */
    public function addRoles(roles $roles)
    {
        $this->roles[] = $roles;

        return $this;
    }
    // ......
}

角色实体类(同样,相关部分)

class roles implements RoleInterface
{
    // .........

    /**
     * @ORM\ManyToMany(targetEntity="users", mappedBy="roles")
     */
    private $users;

    public function __construct()
    {
        $this->users = new ArrayCollection();
    }

   /**
     * Add users
     *
     * @param \Ampisoft\Bundle\etrackBundle\Entity\users $user
     * @return roles
     */
    public function addUser(users $user)
    {
        $this->users[] = $user;

        return $this;
    }
    // .........
}

控制器

public function admin_new_userAction()
{
    $user = new users();
    $form = $this->createForm(new usersType(), $user);

    $request = $this->getRequest();

    // if form is posted
    if ($request->getMethod() === 'POST') {
        $form->bind($request);

        $user->setSalt(md5(time()));

        $encoder = $this->container->get('security.encoder_factory')->getEncoder($user); //get encoder for hashing pwd later
        $tempPassword = $encoder->encodePassword($user->getPassword(), $user->getSalt());
        $user->setPassword($tempPassword);

        // flush to db
        $em = $this->getDoctrine()->getEntityManager();
        $em->persist($user);
        $em->flush();

        return $this->redirect($this->generateUrl('admin_users'));

    }

    // BUILD FORM
    return $this->render('etBundle:Admin:new_user.html.twig', array(
        'form' => $form->createView(),
    ));
}

usersType类(我打算用它来编辑用户以及监听器)

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
        $user = $event->getData();
        $form = $event->getForm();

        // check if the User object is "new"
        if (!$user || null === $user->getId()) {
            $form->add('username', 'text');
            $form->add('firstname', 'text');
            $form->add('lastname', 'text');
            $form->add('password', 'repeated', array(
                'type' => 'password',
                'invalid_message' => 'The password fields must match.',
                'options' => array('attr' => array('class' => 'password-field')),
                'required' => false,
                'first_options' => array('label' => 'Password'),
                'second_options' => array('label' => 'Repeat Password'),
            ));
            $form->add('email', 'repeated', array(
                'type' => 'email',
                'invalid_message' => 'The email address fields must match.',
                'options' => array('attr' => array('class' => 'email-field')),
                'required' => true,
                'first_options' => array('label' => 'Email'),
                'second_options' => array('label' => 'Repeat Email'),
            ));
            $form->add('email', 'repeated', array(
                'type' => 'email',
                'invalid_message' => 'The email address fields must match.',
                'options' => array('attr' => array('class' => 'email-field')),
                'required' => true,
                'first_options' => array('label' => 'Email'),
                'second_options' => array('label' => 'Repeat Email'),
            ));
            $form->add('lastLogged', 'hidden');
            $form->add('roles', 'entity', array(
                'class' => 'etBundle:roles',
                'property' => 'name',
            ));

        } else {
            $form->add('id', 'hidden');
            $form->add('username', 'text');
            $form->add('firstname', 'text');
            $form->add('lastname', 'text');
            $form->add('password', 'repeated', array(
                'type' => 'password',
                'invalid_message' => 'The password fields must match.',
                'options' => array('attr' => array('class' => 'password-field')),
                'required' => false,
                'first_options' => array('label' => 'Password'),
                'second_options' => array('label' => 'Repeat Password'),
            ));
            $form->add('email', 'repeated', array(
                'type' => 'email',
                'invalid_message' => 'The email address fields must match.',
                'options' => array('attr' => array('class' => 'email-field')),
                'required' => true,
                'first_options' => array('label' => 'Email'),
                'second_options' => array('label' => 'Repeat Email'),
            ));

        }

    });

我发现addUser类中有一个roles()方法,但我不确定如何使用它。如果有人能指出我正确的方向,我将非常感激。

** 更新 1 **

我尝试在上面插入建议的setRoles()方法,现在我收到以下内容 error: Catchable Fatal Error: Argument 1 passed to Doctrine\Common\Collections\ArrayCollection::__construct() must be of the type array, object given, called in C:\Dropbox\xampp\htdocs\etrack3\vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.‌​php on line 555 and defined

** 更新 2 ** 解决了这个问题:意识到我的用户/角色实体之间有很多关系/多关系。改为manyToOne / OneToMany,一切都很好。

1 个答案:

答案 0 :(得分:2)

您的class users缺少其构造函数,该构造函数将$roles属性初始化为ArrayCollection实例。我还建议不要使用$this->users[]表示法,而是将这些属性视为真正的属性:

$this->users->add($user);

至于你得到的错误,这取决于Doctrine如何加载它的实体。该错误显示了实体类中的doctrine查找内容,以便设置属性:roles属性应该是公共的,或者您需要一个名称类似于set<ucfirst-name-of-table-field>的方法,或者慢魔法getter / setter界面。

setRolessetUsers方法而言,这是一件简单的事情:

public function setRoles($roles)
{
    $this->roles = $roles;
    return $this;
}

可以选择添加类型提示:

public function setRoles( ArrayCollection $roles)
{
    $this->roles = $roles;
    return $this;
}

我想提及的其他一些问题:

编码标准很重要,请检查最常用的标准here。 Doctrine,Symfony2,ZendFW2,...所有主要参与者都赞同这些标准,你也应该这样做。类名称例如以大写字母开头,因此class users应该变为class Users等... 我还建议不要在doctrine实体上实现Serializable接口,特别是如果你使users Serializable,它可能包含Roles个实例,而不实现Serializable。< / p>