向数组集合添加不同的值
Add distinct values to array collection
在我的应用程序中,我向不同的用户发送通知,这些用户被分配给代理机构,这些用户被分配给文档。因此,无论何时创建文档并将代理分配给该文档,属于该代理的所有用户都应该收到通知。问题:可能会发生这样的情况,即一个用户被分配给多个机构,因此每当通知发出并且他的所有机构都被分配给该文档时,他会收到多次通知。我想避免这种情况,但我不知道如何只将不同的对象添加到我的数组集合中,因为它似乎不像 array_unique功能。
目前看来是这样的:
foreach($document->getAgencies() as $agency) {
if(count($agency->getUseragencies()) > 0){
$users = $agency->getUseragencies();
foreach ($users as $user){
... notifications are generated
$manager->addNotification($user, $notif);
}
}
}
如有任何帮助,我们将不胜感激!
哦,还有背景信息:Agency 是一个自己的实体,User 也是,它们是多对多的关系!
编辑
映射信息:
在实体 机构 中:
/**
* @ORM\ManyToMany(targetEntity="UserBundle\Entity\User", mappedBy="agencies")
**/
private $useragencies;
实体用户
/**
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Agency", inversedBy="useragencies", cascade={"persist"})
* @ORM\JoinTable(name="user_user_agencies",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="iata8", referencedColumnName="iata8")})
* @var \AppBundle\Entity\Agency
**/
private $agencies;
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Notification", mappedBy="user", orphanRemoval=true, cascade={"persist"})
**/
private $notifications;
您需要添加一个条件来处理数组中已有的值。尝试添加类似以下条件的内容。
foreach($user as $user){
if(!in_array($value, $list, true))
虽然您不能在 ArrayCollection
上使用 in_array()
,但您必须构建自己的独特用户数组。
$users = array();
foreach($document->getAgencies() as $agency) {
if(count($agency->getUseragencies()) > 0) {
foreach ($agency->getUseragencies()as $user) {
// ... notifications are generated
if(!in_array($user->getId(), $users)) {
$users[] = $user->getId();
}
}
foreach($users as $userId) {
$manager->addNotification($userId, $notif);
}
}
}
或更简单、成本更低的版本:
$sent = array();
foreach($document->getAgencies() as $agency) {
if(count($agency->getUseragencies()) > 0) {
foreach ($agency->getUseragencies()as $user) {
// ... notifications are generated
if(!in_array($user->getId(), $sent)) { // check if user has already been sent the notification
$manager->addNotification($user, $notif); // send the notification
$sent[] = $user->getId(); // add user to the 'sent' list
}
}
}
}
或者,您可以通过编写 custom DQL 查询(可能在您的 UserRepository
class 中)直接从数据库中获取用户列表来省去很多麻烦。通过完全消除对循环的需要,这将消除代码中的许多复杂性。
我假设您的 Agency
实体也与 Document
实体进行双向映射,我猜是 ManyToMany
。要获取您想要向其发送属于多个机构的通知的用户,并且一个机构可以拥有许多文档,您可以在 DQL 下方使用它来通过提供文档 ID 来获取不同的用户,如果您有任何其他 属性 来识别文件你可以相应地调整 WHERE
条款
SELECT DISTINCT u
FROM YourBundle:User u
JOIN u.agencies a
JOIN a.documents d
WHERE d.id = :documentid
使用查询生成器它会像
$user = $em->getRepository('YourBundle:User');
$user = $user->createQueryBuilder('u')
->select('u')
->join('u.agencies','a')
->join('a.documents','d')
->where('d.id = :documentid')
->setParameter('documentid', $documentid)
->distinct()
->getQuery();
$users= $user->getResult();
ArrayCollection
有一个方法 contains
您可以使用 - link.
在我的应用程序中,我向不同的用户发送通知,这些用户被分配给代理机构,这些用户被分配给文档。因此,无论何时创建文档并将代理分配给该文档,属于该代理的所有用户都应该收到通知。问题:可能会发生这样的情况,即一个用户被分配给多个机构,因此每当通知发出并且他的所有机构都被分配给该文档时,他会收到多次通知。我想避免这种情况,但我不知道如何只将不同的对象添加到我的数组集合中,因为它似乎不像 array_unique功能。
目前看来是这样的:
foreach($document->getAgencies() as $agency) {
if(count($agency->getUseragencies()) > 0){
$users = $agency->getUseragencies();
foreach ($users as $user){
... notifications are generated
$manager->addNotification($user, $notif);
}
}
}
如有任何帮助,我们将不胜感激! 哦,还有背景信息:Agency 是一个自己的实体,User 也是,它们是多对多的关系!
编辑 映射信息: 在实体 机构 中:
/**
* @ORM\ManyToMany(targetEntity="UserBundle\Entity\User", mappedBy="agencies")
**/
private $useragencies;
实体用户
/**
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Agency", inversedBy="useragencies", cascade={"persist"})
* @ORM\JoinTable(name="user_user_agencies",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="iata8", referencedColumnName="iata8")})
* @var \AppBundle\Entity\Agency
**/
private $agencies;
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Notification", mappedBy="user", orphanRemoval=true, cascade={"persist"})
**/
private $notifications;
您需要添加一个条件来处理数组中已有的值。尝试添加类似以下条件的内容。
foreach($user as $user){
if(!in_array($value, $list, true))
虽然您不能在 ArrayCollection
上使用 in_array()
,但您必须构建自己的独特用户数组。
$users = array();
foreach($document->getAgencies() as $agency) {
if(count($agency->getUseragencies()) > 0) {
foreach ($agency->getUseragencies()as $user) {
// ... notifications are generated
if(!in_array($user->getId(), $users)) {
$users[] = $user->getId();
}
}
foreach($users as $userId) {
$manager->addNotification($userId, $notif);
}
}
}
或更简单、成本更低的版本:
$sent = array();
foreach($document->getAgencies() as $agency) {
if(count($agency->getUseragencies()) > 0) {
foreach ($agency->getUseragencies()as $user) {
// ... notifications are generated
if(!in_array($user->getId(), $sent)) { // check if user has already been sent the notification
$manager->addNotification($user, $notif); // send the notification
$sent[] = $user->getId(); // add user to the 'sent' list
}
}
}
}
或者,您可以通过编写 custom DQL 查询(可能在您的 UserRepository
class 中)直接从数据库中获取用户列表来省去很多麻烦。通过完全消除对循环的需要,这将消除代码中的许多复杂性。
我假设您的 Agency
实体也与 Document
实体进行双向映射,我猜是 ManyToMany
。要获取您想要向其发送属于多个机构的通知的用户,并且一个机构可以拥有许多文档,您可以在 DQL 下方使用它来通过提供文档 ID 来获取不同的用户,如果您有任何其他 属性 来识别文件你可以相应地调整 WHERE
条款
SELECT DISTINCT u
FROM YourBundle:User u
JOIN u.agencies a
JOIN a.documents d
WHERE d.id = :documentid
使用查询生成器它会像
$user = $em->getRepository('YourBundle:User');
$user = $user->createQueryBuilder('u')
->select('u')
->join('u.agencies','a')
->join('a.documents','d')
->where('d.id = :documentid')
->setParameter('documentid', $documentid)
->distinct()
->getQuery();
$users= $user->getResult();
ArrayCollection
有一个方法 contains
您可以使用 - link.