所以我有一个字符串,代表几个对象(在这种情况下是标签),即:“php,mysql,doctrine2”假设我的数据库已经有“php”和“doctrine2”。现在我想要添加缺失元素的最佳方法(在本例中为 mysql)。
我应该为每个元素创建一个对象并只使用持久/同步或其他东西,还是有更好的方法?
无论如何,我需要最后的所有对象将它们添加到一个新对象(具有简单的多对多关系)。
我会很高兴有任何建议。
所以我有一个字符串,代表几个对象(在这种情况下是标签),即:“php,mysql,doctrine2”假设我的数据库已经有“php”和“doctrine2”。现在我想要添加缺失元素的最佳方法(在本例中为 mysql)。
我应该为每个元素创建一个对象并只使用持久/同步或其他东西,还是有更好的方法?
无论如何,我需要最后的所有对象将它们添加到一个新对象(具有简单的多对多关系)。
我会很高兴有任何建议。
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);
我有一个类似的问题,我必须将实体集合与外部源同步。但是,我的问题不仅需要添加,还需要更新和删除。我使用代码将 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);
}
);