Magentoでコレクションを複製する方法は?


12

このコレクションに対して2つの異なる操作を実行するメソッドに1つのコレクションがあります。そのため、同じコレクションの2つの別々のコピーが必要になり、2つのコレクションの1つを元のコレクションに再度割り当てて返します。

これを簡単にするために、というオブジェクトコレクションがあるとし$collectionます。

今、組み込みのMagentoコレクションのクローンがあるかどうかわからないので、PHPクローンで試しています。

$coll1 = clone $collection;
$coll2 = clone $collection;

今、私は元のコレクションのこれらの2つの別々のクローンで異なる操作を実行しようとしています。

$coll1->getSelect()->where('some where condition');
$coll2->getSelect()->where('some different where condition');
if($coll1->count() == 0) {
    $collection = $coll2;
} else {
    $collection = $coll1;
}

しかし、奇妙なことに、これらのクローン化されたコレクションには、where条件が割り当てられています!$ coll1の条件は、$ coll2の条件とともに$ coll2に適用され、その逆も同様です。

誰もこれを達成する方法を知っていますか?

ありがとう!

回答:


14

ディープクローン作成が必要なPHPクローン演算子を使用するには、プロパティにオブジェクトを格納するクラスが__cloneメソッドを実装してオブジェクトをコピーする必要があります。定義しない場合、両方のインスタンスのプロパティは同じオブジェクトを参照します。

Magentoは、そのコレクションの要約に__cloneを実装していないため、必要に応じてディープクローンをサポートしていません。

コレクションの複製はかなり高価になる可能性があるため、私の提案は、あなたがしたいことを達成するための他の方法を探すことです。

(たとえば)指定した例を変更して、選択を複製し、変更してロードしたレコードの数を選択し、その結果に基づいてコレクションを変更します。コレクションをロードして、使用するコレクションを判断するためだけにカウントするのではないため、これもパフォーマンスが向上します。

編集:以下は、コレクションをロードまたは実際に変更せずにカウントを取得する方法を示しています。

$collection = Mage::getModel(...)->getCollection();

$count = $collection->getSelectCountSql();
$count->where('some where condition');
if ($count->query()->fetchColumn() == 0) {
    ...
} else {
    ...
}

ほんの少しの詳細:どこに情報が保存さ$collection->getSelect()れ、コレクション自体には保存されません。
ファビアンブレシュミット

ご回答ありがとうございます。しかし、where条件のみを適用した後、コレクションカウントを知りたいので、そのカウントのみに基づいて、異なるwhere条件を使用するかどうかを決定します。方法をよりよく理解するために、コードスニペットを投稿できますか?
MagExt

コード例を使用して回答を更新しました。@FabianBlechschmidtが指摘したように、選択はどこにあります。これは、コレクションオブジェクトが複製されるときに複製されず、両方が同じ選択オブジェクトインスタンスを参照するため、特定の問題が発生する場所です。
-davidalger

更新していただきありがとうございます。私はすでにそのようなソリューションを手に入れたので、これを試していません。
MagExt

実際、コレクションの複製に問題がある場合は、プロセスでシリアル化と非シリアル化が役立つ場合があります。PHPでクローンを作成する他の代替手段もあります。しかし、デビッドは全体的に正しいです...基本的に、オブジェクトを複製するとき、それに接続されているネストされたオブジェクトへのポインタも複製していますが、彼の答えは根本的な問題を適切に述べていませんでした。
mprototype

1

@davidalgerの答えを拡張するために、カウントとは異なる操作を行いたい場合に選択をリセットできます。

$select= $collection->getSelectCountSql()->reset();

$select
    ->from('newsletter_subscriber', array('some_column'))
    ->distinct();

ただし、これによりコレクションが変更されるため、プロセスの後半で有害な影響が生じる可能性があります。

より良い方法は、何らかの方法で選択を複製することですが、オブジェクトに複雑な型が含まれるため(Varien_Db_SelectまたはZend_Db_Selectには__cloneメソッドがあります)、浅いコピーでは切り取りません。

これを回避する1つの方法は、選択データを保存、変更、クエリを実行し、元の選択データを戻すことです。

例についてはこちらをご覧くださいhttps : //ka.lpe.sh/2013/05/23/magento-clone-collection-how-to-clone-collection-in-magento/

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.