Вопрос

У меня есть одна коллекция в методе, где я хочу выполнить две разные операции в этой коллекции. Итак, я хочу две отдельные копии одной и той же коллекции, а затем снова назначал одну из двух коллекций для оригинальной коллекции и вернул ее.

Чтобы сделать это простым, предположим, что у меня есть коллекция объектов под названием $collection.

Теперь я пробую это с клонированием PHP, так как не знаю, есть ли какая -либо коллекция Magento Coloning встроенным или нет.

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

Теперь я пытаюсь выполнить различные операции на этих двух отдельных клонах оригинальной коллекции, что -то вроде.

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

Но странная вещь в том, что обе эти клонированные коллекции имеют оба условия, назначенные! Состояние $ coll1 применяется к $ coll2 вместе с условием $ coll2 и наоборот.

Кто -нибудь знает, как это достичь?

Спасибо!

Это было полезно?

Решение

Использование оператора клона PHP, где требуется глубокое клонирование, требуется классы, которые хранят объекты на свойствах, реализуя метод __clone для копирования объектов. Если они не определяют это, свойства на обоих случаях будут ссылаться на один и тот же объект.

Magento не внедряет __clone в его рефератах сбора, и поэтому не поддерживает глубокое клонирование, как вы этого хотите.

Мое предложение состоит в том, чтобы искать другие способы выполнить то, что вы хотите сделать, поскольку клонирование коллекции может быть довольно дорогим.

Пример, который вы дали (например,), можно изменить, чтобы клонировать Select, изменить его, чтобы выбрать количество записей, которые он загрузил бы, а затем на основе этого результата изменить коллекцию. Это также будет работать лучше, так как вы не будете загружать коллекцию и подсчитывать ее, чтобы определить, какой из них использовать.

РЕДАКТИРОВАТЬ: Следующее демонстрирует, как захватить счет без загрузки или фактического изменения коллекции.

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

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

Другие советы

Чтобы расширить ответ @Davidalger, вы можете перезагрузить Выберите, если вы хотите выполнить другую операцию, чем количество - например,:

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

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

Будьте осторожны, хотя это может иметь пагубные эффекты позже в процессе, поскольку это изменяет коллекцию.

Лучшим способом было бы каким -то образом клонировать выбор, но неглубокая копия не будет ее сокращать, поскольку объект содержит сложные типы (varien_db_select или zend_db_select __clone метод).

Один из способов обойти это - сохранить данные Select, изменить его, запустить запрос, а затем поместить исходные данные Select.

Смотрите здесь для примера:https://ka.lpe.sh/2013/05/23/magento-clone-collection-how-to-clone-collection-in-magento/

Лицензировано под: CC-BY-SA с атрибуция
Не связан с magento.stackexchange
scroll top