提问人:Silfers IsNobody 提问时间:2/25/2016 最后编辑:Silfers IsNobody 更新时间:2/11/2020 访问量:9631
PHP学说:测试对象是否在ArrayCollection中
PHP Doctrine : Test if an object is in an ArrayCollection
问:
我正在尝试使用ArrayCollection::contains方法来查找对象是否已经在我的集合中,但是当我这样做时:
//My ArrayCollection
$lesRoles = $drt->getDrtApplication()->getRoles();
$leRole = $lesRoles->first();
echo "Property appNom : ".$leRole->getRleApplication()->getAppNom()."// Property appRole : ".$leRole->getRleId()." <br>";
$role = new \Casgaya\Role(2,$drt->getDrtApplication());
echo "Property appNom : ".$role->getRleApplication()->getAppNom()."// Property appRole : ".$role->getRleId()." <br>";
var_dump($lesRoles->contains($role));
结果是: 属性 appNom : CORA// 属性 appRole : 2 属性 appNom : CORA//
属性 appRole :
2
bool(false)
由于 appNom 和 rleId 是实体 Role 拥有的仅有的两个属性,因此我正在跳跃,它将返回 true。
编辑新测试用例:
echo "Test object role : <br>";
var_dump($lesRoles==$role);
echo"<br>";
echo "Test integer property rleID from object role : <br>";
var_dump($role->getRleId() == $leRole->getRleId());
echo"<br>";
echo "Test Application object property RleApplication from object role : <br> ";
var_dump($role->getRleApplication() == $leRole->getRleApplication());
结果是:
属性 appNom : CORA// 属性 appRole : 2 属性 appNom : CORA// 属性 appRole : 2
测试对象角色:bool(false) 测试对象角色的整数属性 rleID:bool(true) 测试应用程序对象
属性 RleApplication from object role :
bool(true)
请注意,当我测试这两个属性的相等性时,它们都是真的。但是当我测试两个整个对象的相等性时,它是错误的。
因此,问题不再是关于 ArrayCollection::contains,而是:
在相等的情况下,根据什么标准比较两个原则实体?
答:
包含( 混合$element ) 检查给定元素是否包含在集合中。只比较元素值,不比较键。两个元素的比较是严格的,这意味着不仅值必须匹配,而且类型也必须匹配。对于对象,这意味着引用相等。
如果你想检查某个角色是否包含在集合中,你可以通过 Doctrine 检索它 - 它将返回相同的对象,因为 Doctrine 通常不会获取已经通过另一个查询获取的实体。
评论
我自己找到了解决方案,这是为有同样问题的人准备的:
我正在使用ArrayCollection::exists方法而不是contains,因此我可以指定应该在哪些标准上建立对象之间的相等性:
就我而言:
$result = $lesRoles->exists(function($key,$element) use ($role)
{
return ($element->getRleApplication() == $role->getRleApplication() && $role->getRleId() == $element->getRleId());
});
请注意,此处的 $key 和 $element 是从集合中测试的当前对象。
I had a same issue:
$Xrepository->removeX($x);
$x->getY()->removeXRelation($x);
In I tested if the relation was existent with
This would failremoveXXXRelation()
ArrayCollection->contains()
contains()
After 2 hours of debugging and trying around the solution was this
$x->getY()->removeXRelation($x);
$Xrepository->removeX($x);
Simply flipping the remove calls.
As you can see Doctrine is doing magic with the object.
This magic starts with the remove call.
A colleague told me about hibernate object lifecycle states, which resolve to:
Not-persisted, Persisted, and Not-Persisted Anymore
It is possible that due to lifecycle state changes your object is generated twice, making the go false (contains checks the objects identity)
That's my theory (tell me if I am wrong)contains()
下一个:自动检查两个对象是否相等?
评论