HAFTUNGSAUSSCHLUSS: Verwenden Sie die Datenbank nach Möglichkeit zum Sortieren. In einigen Fällen möchten Sie jedoch möglicherweise Elemente in einer Sammlung anordnen, die (noch) nicht in der Datenbank gespeichert sind, z. B. nachdem Sie dem Angebot während des Vorgangs dynamisch Elemente hinzugefügt haben collectTotals()
. Dann ist dieser Ansatz nützlich.
Leider nicht, Varien_Data_Collection
ist in dieser Hinsicht nicht sehr flexibel. Um Elemente in einer Sammlung neu zu ordnen, müssen Sie sie entfernen und in der gewünschten Reihenfolge erneut hinzufügen.
In Ihrem speziellen Fall:
// remove previous items, keep them in $items
$items = $productCollection->getItems();
foreach ($productCollection as $key => $item) {
$collection->removeItemByKey($key);
}
// add new item
$productCollection->addItem($product);
// re-add $items
foreach ($items as $item) {
$productCollection->addItem($item);
}
Update: Leistung
Da es Einwände hinsichtlich der Leistung gibt, habe ich einen kleinen Benchmark für eine echte Produktdatenbank durchgeführt. Beachten Sie, dass das Laden einer Sammlung mit 20.000 Produkten etwas ist, das Sie eigentlich nie tun sollten. Dies soll jedoch nur beweisen, dass das zweimalige Durchlaufen der geladenen Arrays keinen signifikanten Overhead verursacht:
Testskript
$startTime = microtime(true);
$productCollection = Mage::getResourceModel('catalog/product_collection')->load();
printf("Loaded %d products. Time: %.2fs Memory: %s\n",
$productCollection->count(), microtime(true)-$startTime, number_format(memory_get_usage(true)));
// remove previous items, keep them in $items
$items = $productCollection->getItems();
foreach ($productCollection as $key => $item) {
$productCollection->removeItemByKey($key);
}
printf("Removed items. Time %.2fs Memory: %s\n",
microtime(true)-$startTime, number_format(memory_get_usage(true)));
// add new item
$productCollection->addItem(Mage::getModel('catalog/product'));
// re-add $items
foreach ($items as $item) {
$productCollection->addItem($item);
}
printf("Added items. Time %.2fs Memory: %s\n",
microtime(true)-$startTime, number_format(memory_get_usage(true)));
Ausgabe
Geladene 20761 Produkte. Zeit: 3,70 s Speicher: 81.264.640
Elemente entfernt. Zeit 3,92 Speicher: 81.788.928
Elemente hinzugefügt. Zeit 4.31 Speicher: 81.788.928
Und mit einer realistischeren Menge von 100 geladenen Produkten:
100 Produkte geladen. Zeit: 0,11 s Speicher: 10.223.616
Elemente entfernt. Zeit 0,11 s Speicher: 10.223.616
Elemente hinzugefügt. Zeit 0,12 s Speicher: 11.272.192
Ein Auflistungsobjekt verfügt über ein Standardarray namens,
_items
das alle resultierenden Modelle enthält, die von der Datenbankabfrage abgerufen werden. DieaddItem()
Methode existiert in der Klasse.Varien_Data_Collection
Wenn Sie sie sich ansehen, müssen Sie lediglich einen Eintrag an das Ende des Arrays verschieben und unterliegen genau dem gleichen Verhalten wie array_push :Und die
_addItem()
Methode ist wie folgt:Wenn Sie die
addItem()
Methode aufrufen , wird am Ende des Arrays lediglich ein neuer Eintrag mit der ID des Elements hinzugefügt, das Sie hinzufügen, wenn es als Schlüssel vorhanden ist. Andernfalls wird der nächste verfügbare Schlüsselwert für das automatische Inkrementieren verwendet (indem nicht definiert wird) ein Schlüssel).Wenn Sie möchten, dass die Artikel auf eine bestimmte Weise bestellt werden, sollten Sie stattdessen sicherstellen, dass Ihre Datenbankabfrage die Ergebnisse korrekt ordnet, oder den gesamten Artikel
getItems()
mit PHP aus dem Sammlungsobjekt ziehen und dann mit PHP bestellen. Bei weitem am effizientesten ist es, sie in Ihrer Datenbankabfrage korrekt zu ordnen. Die Bearbeitung der Ergebnisse, die über PHP aus der Datenbank abgerufen wurden, ist unzählige Male langsamer.quelle
Ich bekomme jede richtige Lösung. Die folgende Lösung kann funktionieren:
Neues Varien-Sammlungsobjekt erstellen:
Weisen Sie das Produkt zu. Fügen Sie das erste Element hinzu:
Verwenden Sie die Schleife, um den Rest des Produkts zuzuweisen:
quelle
getFirstItem()
Ich hatte die gleiche Aufgabe, der Sammlung ein Element hinzuzufügen wie das erste Element. Unten ist der Code, den ich implementiert habe und der perfekt für mich funktioniert.
Erläuterung
Im obigen Code
$product
wird als erstes Element eine Produktsammlung$collection
hinzugefügt$product
, die dieser Sammlung hinzugefügt wurde .Wenn Sie die
$collection->getSelect()->order($expr);
Position von zwangsweise sortieren verwenden$product
, um sie als erste Position festzulegen, werden die restlichen Elemente nach sortiert$collection->addAttributeToSort( 'price', 'asc');
Hinweis - Es muss
$collection->getSelect()->order($expr);
vor jeder Sortierung nach Code aufgerufen werden.quelle