我在将用户角色存储到数据库中时遇到问题。我使用的是这里写的原始文件:http://symfony.com/doc/current/book/security.html
在这里:http://symfony.com/doc/current/cookbook/security/entity_provider.html
登录 注销正在工作。我可以将用户保存到数据库中,但我不知道如何保存他的角色。是否可以使用此文件,或者我必须再做一个单独提供此文件的文件?我不想使用FOSUser Bundle... 谢谢你的回答。以下是链接:
帐户控制器 http://pastebin.com/ycrLyUcg
注册 http://pastebin.com/Q7se6pnF
注册类型 http://pastebin.com/926tu0hj
用户 http://pastebin.com/aNdQr46C角色 http://pastebin.com/cg7QTk59用户存储库 http://pastebin.com/LHPuy4We
非常感谢您的回答
编辑 10.11.2013 23:00:
- http://pastebin.com/DDygxzDN 帐户控制器.php
- http://pastebin.com/SmSJMm4t 用户.php
- http://pastebin.com/fEZk7JPa 用户角色.php
编辑11.11.2013 15:20
- http://pastebin.com/Zu8w7cQ9 角色.php
在 AccountController 的 createAction
方法中,您从未实际向用户分配Role
;您必须先设置它,然后才能将其用作身份验证过程的一部分。这样的东西应该在给定上述模型的情况下保留Role
。
if ($registrationForm->isValid()) {
...
$role = new Role();
$role->setName('User');
$role->setRole('ROLE_USER');
$roles = new 'Doctrine'Common'Collections'ArrayCollection;
$roles->add($role);
$user->setRoles($roles);
...
}
此外,我会重新考虑在用户和角色之间建立@ManyToMany
关系的要求,@ManyToOne
在这里可能就足够了;无论您是否希望坚持任何类型的关联映射,您都可能需要确保在持久化User
类时,关联的角色也会持久化。为此,您可能需要向User
类添加cascade
指令,如下所示:
class User implements AdvancedUserInterface, 'Serializable
{
...
/**
* @ORM'ManyToMany(targetEntity="Role", inversedBy="users", cascade={"all"})
*/
private $roles;
...
}
Symfony'Component'Security'Core'User
中的默认 User
类也为其用户对象使用角色集合,因此一旦您保留了角色,您就可以只使用现有的 UsernameAuthenticationProvider,希望一切都会正常工作。如果没有,则可能需要自定义身份验证提供程序。
请注意,在上面,我们使用 setRoles()
方法显式分配 $roles
属性;这是因为 getRoles()
的返回类型不是ArrayCollection
,而是基元array
。如果您希望所有内容都"仅与Symfony现有的身份验证提供程序一起工作"getRoles()
据我所知,原始数组是正确的。
重新审视同一问题 (11/10/2013):
"我按照你写的做了,但它试图写入acme_roles表中,我在其中保存角色类型 - 管理员、用户......但我想将用户的角色保存到表中user_roles - 我在那里保存用户 ID 和角色 ID"
鉴于您在聊天中的扩展评论中指示您想要的内容,我的方法是使用三个实体/表来建模您的用户与角色关系。这显然只是解决问题的一种方式。
您的表将是:acme_users
(User
实体)、acme_roles
(Role
实体)和acme_user_roles
(UserRole
实体)。
User
不会直接与Role
对象建立多对多关系,相反,您可以在User
和UserRole
类之间建立一对多关系。- 关联类,
UserRole
(或任何你称呼它)需要一个主键(id
)和两个多对一关系:一个用于User
,一个用于Role
。
没有必要 - 在
Role
类和UserRole
之间创建反向关系,因为你的角色与其他实体是隔离的。 - 在为新创建的
User
分配Role
之前,您需要先查找它,找到它后,您可以使用对$user
和$role
的引用来创建UserRole
,然后将其添加到User
类上的角色集。
以上只是你如何处理这个问题的粗略概述;更详细地说:
您的
User
类应通过@ORM'OneToMany
注释将关系映射到UserRole
实体,例如:/** * @ORM'OneToMany(targetEntity="UserRole", mappedBy="user", cascade={"all"}) */ private $userRoles;
在
User
中,更改getRoles()
方法以返回与UserRoles
关联的实际角色,类似于:/** * @inheritDoc */ public function getRoles() { $roles = array(); foreach ($this->userRoles as $userRole) { $roles[] = $userRole->getRole(); } return $roles; }
在类
User
,添加getUserRoles()
,setUserRoles()
(可能还有addUserRole()
)方法,删除setRoles()
在
UserRole
中,您希望存储实体引用而不是 ID(由于 Doctrine,它们将以任何方式在列中映射为 ID),因此只需将$user_id
和$role_id
分别更改为$user
和$role
,并更改它们的映射(如果您希望通过UserRole
关联分配多个角色, 您需要有一个离散标识/主键,因此添加$id
属性),如下所示:/** * @ORM'Column(type="integer") * @ORM'Id * @ORM'GeneratedValue(strategy="AUTO") */ private $id; /** * @ORM'ManyToOne(targetEntity="User", inversedBy="userRoles", cascade={"all"}) */ private $user; /** * @ORM'ManyToOne(targetEntity="Role", cascade={"all"}) */ private $role;
从
Role
类中删除对$users
的所有引用。在
AccoundController
中,查找要分配的角色(即如果要分配ROLE_USER
查找正确和相应的角色),并将其分配给UserRole
,然后将UserRole
分配给User
,最后保留$user
,例如:$user = $registration->getUser(); $user->setSalt($this->generateSalt()); $user->setIsActive(1); $factory = $this->get('security.encoder_factory'); $encoder = $factory->getEncoder($user); $password = $encoder->encodePassword($user->getPassword(), $user->getSalt()); $user->setPassword($password); $role = $this->getDoctrine() ->getRepository('AcmeAccountBundle:Role') ->find(2); // Finds "ROLE_USER" $userRole = new UserRole(); $userRole->setRole($role); $user->addUserRole($userRole); $em->persist($user); $em->flush();
确保重新生成架构,最直接的方法是运行:
$ php app/console doctrine:database:drop --force $ php app/console doctrine:database:create $ php app/console doctrine:schema:drop --force $ php app/console doctrine:schema:create $ php app/console doctrine:schema:validate
所以问题解决了。我使用了本教程中的文件:http://symfony.com/doc/current/cookbook/security/entity_provider.html。比我不得不这样做:
$ PHP 应用程序/控制台 原则:数据库:丢弃 --强制
$ PHP 应用程序/控制台 原则:数据库:创建
$ PHP 应用程序/控制台原则:模式:丢弃 --force
$ PHP 应用程序/控制台 原则:模式:创建
$ PHP 应用程序/控制台原则:模式:验证
谢谢肖恩·奎因