Có thể thêm phần tử vào bộ sưu tập làm phần tử đầu tiên, tương tự như phương thức này có thêm phần tử vào cuối không?
$product = Mage::getModel('catalog/product')->load(15879);
$productCollection->addItem($product);
Có thể thêm phần tử vào bộ sưu tập làm phần tử đầu tiên, tương tự như phương thức này có thêm phần tử vào cuối không?
$product = Mage::getModel('catalog/product')->load(15879);
$productCollection->addItem($product);
Câu trả lời:
TUYÊN BỐ TỪ CHỐI: Sử dụng cơ sở dữ liệu cho các mục đích sắp xếp bất cứ khi nào có thể. Tuy nhiên, trong một số trường hợp, bạn có thể muốn sắp xếp các mục trong bộ sưu tập chưa được lưu trữ trong cơ sở dữ liệu (ví dụ) sau khi tự động thêm các mục vào báo giá trong thời gian
collectTotals()
. Sau đó, phương pháp này sẽ hữu ích.
Thật không may, Varien_Data_Collection
không linh hoạt về mặt này. Để sắp xếp lại các mục trong bộ sưu tập, bạn cần xóa chúng và thêm lại chúng theo thứ tự mong muốn.
Trong trường hợp cụ thể của bạn:
// 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);
}
Vì có sự phản đối về hiệu suất, tôi đã làm một điểm chuẩn nhỏ trên cơ sở dữ liệu sản phẩm thực sự. Lưu ý rằng việc tải bộ sưu tập với các sản phẩm 20K là điều bạn không bao giờ thực sự nên làm nhưng điều này chỉ để chứng minh điểm lặp đi lặp lại trên các mảng được tải hai lần không thêm chi phí đáng kể:
Kiểm tra tập lệnh
$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)));
Đầu ra
Đã tải 20761 sản phẩm. Thời gian: 3,70 giây Bộ nhớ: 81,264,640
Các mục bị loại bỏ. Thời gian 3,92 Bộ nhớ: 81,788,928
Đã thêm mục. Bộ nhớ thời gian 4.31: 81.788.928
Và với số lượng thực tế hơn 100 sản phẩm được tải:
Đã tải 100 sản phẩm. Thời gian: 0.11s Bộ nhớ: 10.223.616
Các mục bị loại bỏ. Bộ nhớ thời gian 0.11s: 10.223.616
Đã thêm mục. Bộ nhớ thời gian 0,12s: 11,272,192
Một đối tượng bộ sưu tập có một mảng tiêu chuẩn được gọi là _items
chứa tất cả các mô hình kết quả được truy vấn bởi cơ sở dữ liệu. Các addItem()
phương pháp tồn tại trong lớp Varien_Data_Collection
và nếu bạn nhìn vào nó tất cả nó là đẩy một mục vào cuối mảng và có thể chính xác hành vi tương tự như array_push :
public function addItem(Varien_Object $item)
{
$itemId = $this->_getItemId($item);
if (!is_null($itemId)) {
if (isset($this->_items[$itemId])) {
throw new Exception('Item ('.get_class($item).') with the same id "'.$item->getId().'" already exist');
}
$this->_items[$itemId] = $item;
} else {
$this->_addItem($item);
}
return $this;
}
Và _addItem()
phương pháp như sau:
protected function _addItem($item)
{
$this->_items[] = $item;
return $this;
}
Do đó, tất cả những gì xảy ra khi gọi addItem()
phương thức là một mục nhập mới được thêm vào cuối mảng bằng cách sử dụng id của mục bạn đang thêm nếu nó tồn tại dưới dạng khóa, nếu không sử dụng giá trị khóa tăng tự động có sẵn tiếp theo (bằng cách không xác định một chìa khóa).
Nếu bạn cần phải sắp xếp các mục theo một cách cụ thể, thay vào đó, bạn nên đảm bảo truy vấn cơ sở dữ liệu của mình sắp xếp kết quả chính xác hoặc kéo tất cả các mục từ đối tượng bộ sưu tập bằng cách sử dụng getItems()
và sau đó đặt hàng bằng PHP. Bởi FAR hiệu quả nhất là sắp xếp chúng một cách chính xác trong truy vấn cơ sở dữ liệu của bạn, thao tác các kết quả một khi được kéo từ cơ sở dữ liệu qua PHP chậm hơn vô số lần.
Tôi nhận được bất kỳ giải pháp thích hợp. Giải pháp tốt có thể làm việc:
Tạo đối tượng bộ sưu tập varien mới:
$collection- = new Varien_Data_Collection();
$product = Mage::getModel('catalog/product')->load(15879);
Chỉ định sản phẩm thêm phần tử đầu tiên:
$collection->addItem($product);
sử dụng vòng lặp gán phần còn lại của sản phẩm:
foreach($productCollection as $eachProd):
$collection->addItem($eachProd);
endforeach;
$productCollection=$collection;
getFirstItem()
Tôi đã có cùng một nhiệm vụ để thêm phần tử vào bộ sưu tập như phần tử đầu tiên. Phần mềm là mã tôi đã triển khai và hoạt động hoàn hảo cho tôi.
$product = Mage::Model('catalog/product')->load(product_id);// product/element to add as first element
$collection = Mage::Model('catalog/product')->getCollection();
$collection->addAttributeToSelect.... // general code to select attributes
$collection->addAttributeToFilter.... // general code to apply filter
if($product && $product->getId()){ **// product to add as first element**
$collection->addItem($product); // added product to collection
$expr = new Zend_Db_Expr("`e`.`entity_id` = {$product->getId()} desc");
$collection->getSelect()->order($expr); **// $product will be order by DESC to set as first element**
}
$collection->addAttributeToSort( 'price', 'asc'); // this sorting will apply on remaining elements in the collection.
Trong đoạn mã trên, $product
cần thiết để thêm làm phần tử đầu tiên, tạo bộ sưu tập sản phẩm $collection
, thêm vào $product
bộ sưu tập đó.
Sử dụng $collection->getSelect()->order($expr);
vị trí sắp xếp mạnh mẽ $product
để đặt làm vị trí đầu tiên và phần còn lại của các yếu tố sẽ được sắp xếp theo$collection->addAttributeToSort( 'price', 'asc');
Lưu ý - Phải gọi $collection->getSelect()->order($expr);
trước khi sắp xếp theo mã.