gpt4 book ai didi

交响乐 4 : ArrayCollection add not persisting in database

转载 作者:行者123 更新时间:2023-12-02 10:07:03 24 4
gpt4 key购买 nike

我在 Symfony 中有以下实体:

class User implements AdvancedUserInterface, \Serializable {
...
private $roles;
...

public function __construct()
{
...
$this->roles = new ArrayCollection();
// Default role for evey user (new entity);
$this->roles->add("ROLE_USER");
...
}

...

function getRoles() {
return $this->roles->toArray();
}

...

function addRole($role){
$this->roles->add($role);
}

function removeRole($role){
$this->roles->remove($role);
}

...

public function serialize()
{
return serialize(array(
...
$this->roles,
...
));
}

/** @see \Serializable::unserialize() */
public function unserialize($serialized)
{
list (
...
$this->roles,
...
) = unserialize($serialized, ['allowed_classes' => false]);
}
}

当我注册一个用户时,默认角色 (ROLE_USER) 已正确添加。但是当我尝试编辑一个时,数据库记录没有改变:

public function UserAddRole(Request $request){
$userId = $request->request->get("userId");
$role = "ROLE_" . strtoupper($request->request->get("role"));

if($role == "ROLE_USER"){
throw $this->createNotFoundException(
'Cannot remove ROLE_USER role'
);
}

$user = $this->getDoctrine()
->getRepository(User::class)
->findOneBy(array(
'id' => $userId
));

if (!$user) {
throw $this->createNotFoundException(
'User not found'
);
}

$user->addRole($role);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($user);
$entityManager->flush();

return new Response("<pre>".var_dump($user->getRoles())."</pre>");
}

此字段没有任何限制,目前只有硬编码值。

响应中返回的数组包含我想要的角色,但不包含数据库(通过重新加载页面并直接在 MySQL 中进行检查。

有什么想法吗?

谢谢

最佳答案

这里发生了一些不同的事情。根据您上面的评论,您说您正在映射 $rolesarray类型。这是通过调用 native PHP 函数 serialize(...) 存储在数据库中的。和unserialize(...) 。这意味着如果一个对象具有 ROLE_USER 的角色和ROLE_ADMIN ,数据将如下所示:

a:2:{i:0;s:9:"ROLE_USER";i:1;s:10:"ROLE_ADMIN";}

当 Doctrine 加载你的对象时,它将使用内部 PHP array输入来存储此数据,这意味着 $this->roles运行时值为 array('ROLE_USER', 'ROLE_ADMIN')在这个例子中。

类似的类型是 simple_array ,它在应用程序中的行为相同,但将值作为逗号分隔的列表存储在数据库中。因此,在这种情况下,您的数据库数据将是:

ROLE_USER,ROLE_ADMIN

当前在您的构造函数中,您正在使用 Doctrine ArrayCollection输入初始化$roles作为一个集合。但是,如果该字段映射为 array ,从数据库检索对象后,$roles将是 PHP array类型,而不是 ArrayCollection目的。为了说明差异:

// the constructor is called; $roles is an ArrayCollection
$user = new User();

// the constructor is not called; $roles is an array
$user = $entityManager->getRepository(User::class)->findOneById($userId);

一般来说,实际上在我遇到的每种情况下,您只想初始化为 ArrayCollection对于关联映射,并使用 arraysimple_array对于标量值,包括 Roles 属性。

您仍然可以实现您想要的addRole(...)removeRole(...)使用一点点 PHP 的行为。例如,使用Doctrine注解映射:

use Doctrine\ORM\Mapping as ORM;

...

/**
* @ORM\Column(name="roles", type="simple_array", nullable=false)
*/
private $roles;

...

/**
* Add the given role to the set if it doesn't already exist.
*
* @param string $role
*/
public function addRole(string $role): void
{
if (!in_array($role, $this->roles)) {
$this->roles[] = $role;
}
}

/**
* Remove the given role from the set.
*
* @param string $role
*/
public function removeRole(string $role): void
{
$this->roles = array_filter($this->roles, function ($value) use ($role) {
return $value != $role;
});
}

(请注意,除非您使用 PHP 7 或更高版本,否则您将无法使用类型提示)

关于交响乐 4 : ArrayCollection add not persisting in database,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51518036/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com