1

Magento からプルした製品で for ループを使用しようとしています。そして、ループ内の製品でインデックスを使用したいときにクラッシュします。

$collection = Mage::getModel('catalog/product')->getCollection();

$collectionLength = count($collection);
for($j = 0; $j < $collectionLength; $j++)
{
     $productFromStore = $collection[$j];//it crashes on this line of code
     $sku = $productFromStore->getSku();
}

しかし、foreach ループを使用すると、すべての製品に到達できます。

foreach($collection as $product)
{
     // this code works fine
     $sku = $product->getSku(); 
}

誰かが何がうまくいかないのか、そしてその理由を説明できますか?

ありがとう。

4

6 に答える 6

4

まず、コレクションオブジェクトを配列として反復しようとすると、エラーが発生します:

致命的なエラー: タイプ Mage_Catalog_Model_Resource_Product_Collection のオブジェクトを配列として使用できません

、2 番目の for ループは、コレクションを反復するための最良の方法ではありません。第三に、最良の方法は、magento リソース イテレータを使用することです。

Mage::getSingleton('core/resource_iterator')
        ->walk(
           $query->getSelect(), 
           array(array($this,'callbackFunction')));

以下に例を示します。

public function someGetCollectionMethod()
{
    $products = Mage::getModel('catalog/product')->getCollection();
    Mage::getSingleton('core/resource_iterator')
              ->walk(
                   $products->getSelect(), 
                   array(array($this, 'productsCallback')));
}

public function productsCallback($args)
{
    $product = Mage::getModel('catalog/product');
    $prod = $product->load($args['row']['entity_id']);
    Zend_Debug::dump($prod->getSku());
}

楽しいコーディング、アダム

于 2018-01-09T12:23:52.450 に答える
3

Magento の ORM のコレクション クラスは、最終的Varien_Data_Collectionに実装するサブクラスIteratorAggregateです。これが、コレクション オブジェクトを配列のような方法 (つまりforeach) で操作できるのに、forループでは機能しない理由です。1 つには、オブジェクト内の要素 (_items配列メンバー)へのキーベースの直接アクセスはありません_items。配列のキーが行 ID に基づいていることを考えると、残念です。

結論:forループ内でコレクション アイテムを操作するのは簡単ではありませんIteratorAggregate

両方の例を次に示します。コレクションのアイテムを直接操作する必要がある場合は、 を使用できますが$collection->getItems()_items配列キーはデータに基づいているため、連続していない可能性があることに注意してください。nameまた、 Magento の EAV パターンを使用して保存されたコレクションに属性値を追加する必要があることに注意してください。

<?php
header('Content-Type: text/plain');

include('app/Mage.php');
Mage::app();

$collection = Mage::getResourceModel('catalog/product_collection');
$collection->addAttributeToSelect('name');

//for loop - not as much fun
for ($j=0;$j<count($collection);$j++) {  //count() triggers $collection->load()
    $items = $collection->getItems();
    $item = current($items);
    echo sprintf(
        "%d:\t%s\t%s\n",
        $k,
        $item->getSku(),
        $item->getName()
    );
    next($items); //advance pointer
}

//foreach - a bit better
foreach ($collection as $k => $product) {
    echo sprintf(
        "%d:\t%s\t%s\n",
        $k,
        $product->getSku(),
        $product->getName()
    );
}

疑問に思っている場合に備えて: PHP での FOR と FOREACH のパフォーマンス

于 2013-08-30T15:31:03.800 に答える