1

したがって、いくつかのオブジェクト(この場合はタグ)を表す文字列があります。つまり、「php、mysql、doctrine2」データベースにすでに「php」と「doctrine2」があるとします。今、私は不足している要素(この場合はmysql)を追加するための最良の方法が必要です。

すべての要素に対してオブジェクトを作成し、persist / syncなどを使用する必要がありますか、それともより良い方法がありますか?

とにかく(単純な多対多の関係で)新しいオブジェクトにそれらを追加するには、とにかく最後にすべてのオブジェクトが必要です。

どんな提案でも嬉しいです。

4

2 に答える 2

2

1)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);
于 2012-04-27T13:08:54.773 に答える
0

エンティティコレクションを外部ソースと同期する必要があるという同様の問題がありました。しかし、私の問題には、追加だけでなく、更新と削除も必要でした。コードを使用してArrayCollectionを別の配列と比較し、その違いに基づいてCRUDメソッドaddを呼び出しました。ドキュメントからわかる限り、doctrineはこれをネイティブに処理しません。平均パフォーマンスは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);
    }
);
于 2015-02-19T18:41:32.163 に答える