所以我有一个字符串,代表几个对象(在这种情况下是标签) 即:“php,mysql,doctrine2” 假设我的数据库已经有“php”和“doctrine2”。 现在我想要最好的方法来添加缺少的元素(在这种情况下是mysql)。
我应该为每个元素创建一个对象,只使用persist / sync或者其他东西,还是有更好的方法?
无论如何,我还需要最后的所有对象将它们添加到一个新对象(具有简单的多对多关系)。
我对任何建议都很满意。
答案 0 :(得分:2)
1)将所有标签名称通过单个查询拉出到数组中
2)使用array_filter和闭包来检测数据集中不存在的标签
3)为新标签创建插入
$currentTags = getCurrentTagsArray();
$newTags = explode(',', 'php,mysql,doctrine2');
$newTagsToSave = array_filter($currentTags, function($item) use ($newTags){
if (in_array($item, $newTags))
{
return false;
}
return true;
});
或者...
您可以使用Doctrine 2的ArrayCollection包装器(\ Doctrine \ Common \ Collections \ ArrayCollection()),它与上面的实现几乎完全相同(您仍需要传递闭包)。
$myCollection->filter($closure);
答案 1 :(得分:0)
我遇到了类似的问题,我必须将实体集合与外部源同步。但是,我的问题不仅需要添加,还需要更新和删除。我使用代码将ArrayCollection与另一个数组区分开来,并根据差异调用CRUD方法。就我从文档中可以看出,学说本身并没有处理这个问题。平均性能应该是O(n)但需要一些记忆。
/**
* @param array $source - the array we are starting with
* @param array $new - the array we want to end with
* @param $fnHash - function used to determine object equality, not based on object id
* @param $fnUpdate - function to perform update of existing object, takes current object and new object as params
* @param $fnAdd - function to perform insert
* @param $fnDelete - function to perform delete
*/
public static function syncArrays(array $source, array $new,
$fnHash, $fnUpdate, $fnAdd, $fnDelete)
{
// make modifiable array copies mapped by hashes of the elements
$sourceKeys = array_map($fnHash, $source);
$hasKeys =count($sourceKeys) > 0;
$newarray = ($hasKeys) ? array_combine(array_map($fnHash, $new), $new) : $new;
if ($hasKeys) { // true => may have updates or deletes
$sourcearray = array_combine($sourceKeys, $source);
// updates
foreach ($sourceKeys as $hashkey) {
if (isset($sourcearray[$hashkey]) && isset($newarray[$hashkey])) {
$fnUpdate($sourcearray[$hashkey], $newarray[$hashkey]);
unset($sourcearray[$hashkey]);
unset($newarray[$hashkey]);
}
}
// deletes
foreach ($sourcearray as $entity) {
$fnDelete($entity);
}
}
//adds
foreach ($newarray as $entity) {
$fnAdd($entity);
}
}
我称之为更新我的学说关联$ parentEntity-> getPayments()的方式是:
ArrayHelper::syncArrays($parentEntity->getPayments()->toArray(), $newPayments,
function($entity) {return $a->getName();}, // hash function
function($current, $new) {
$current->setTotal($new->getTotal()); // update function
},
function($a) use ($parent, $manager) {
$parent->addVendorPaymentObject($a); // add function
$manager->persist($a);
},
function($a) use ($manager) { // delete function
$manager->remove($a);
}
);