我试图在我从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();
}
有人能解释出现了什么问题吗?为什么?
感谢。
答案 0 :(得分:3)
Magento的ORM中的集合类最终子类Varien_Data_Collection
实现了IteratorAggregate
;这就是为什么你能够以类似数组的方式使用集合对象(即foreach
),但不能让它适用于for
循环。首先,dThere没有对对象内部元素的直接基于密钥的访问(_items
数组成员) - 不幸的是,假设_items
数组的密钥基于行ID。 / p>
结论:在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()
);
}
以防万一你想知道:Performance of FOR vs FOREACH in PHP
答案 1 :(得分:3)
首先,您尝试将集合对象作为数组进行迭代 这是错误:
致命错误:无法使用类型的对象 Mage_Catalog_Model_Resource_Product_Collection as array
,第二个for循环不是迭代集合的最好方法更好的是foreach循环因为循环需要计算数组emelents foreach不需要它。 第三,最好的方法是使用magento资源迭代器。
SKWMediaConstraints* constraints = [[SKWMediaConstraints alloc] init];
constraints.maxWidth = 960;
constraints.maxHeight = 540;
// constraints.cameraPosition = SKW_CAMERA_POSITION_BACK;
constraints.cameraPosition = SKW_CAMERA_POSITION_FRONT;
_msLocal = [SKWNavigator getUserMedia:constraints];
//////////////////// END: Get Local Stream /////////////////////////
// Initialize views
if ((nil != self.navigationItem) && (nil == self.navigationItem.title))
{
NSString* strTitle = @"Video Conference";
[self.navigationItem setTitletrTitle];
}
CGRect rcScreen = self.view.bounds;
if (NSFoundationVersionNumber_iOS_6_1 < NSFoundationVersionNumber)
{
CGFloat fValue = [UIApplication sharedApplication].statusBarFrame.size.height;
rcScreen.origin.y = fValue;
if (nil != self.navigationController)
{
if (NO == self.navigationController.navigationBarHidden)
{
fValue = self.navigationController.navigationBar.frame.size.height;
rcScreen.origin.y += fValue;
}
}
}
// Initialize Local video view
CGRect rcLocal = CGRectZero;
if (UIUserInterfaceIdiomPad == [UIDevice currentDevice].userInterfaceIdiom)
{
rcLocal.size.width = rcScreen.size.width / 5.0f;
rcLocal.size.height = rcScreen.size.height / 5.0f;
}
else
{
rcLocal.size.width = rcScreen.size.height / 5.0f;
rcLocal.size.height = rcLocal.size.width;
}
rcLocal.origin.x = rcScreen.size.width - rcLocal.size.width - 8.0f;
rcLocal.origin.y = rcScreen.size.height - rcLocal.size.height - 58.0f; // changed from 8 to 78 so to present this view above control views
rcLocal.origin.y -= self.navigationController.toolbar.frame.size.height;
// New frames for local and remote video views
CGRect rcRemoteNew;
rcRemoteNew.origin.x = 0.0;
rcRemoteNew.origin.y = 0.0;
rcRemoteNew.size.width = SCREEN_WIDTH;
rcRemoteNew.size.height = SCREEN_HEIGHT;
//////////// START: Add Remote & Local SKWVideo to View ///////////
SKWVideo* vwRemote = [[SKWVideo alloc] initWithFrame:rcRemoteNew];
[vwRemote setBackgroundColorUIColor blackColor]];
[vwRemote setTag:TAG_REMOTE_VIDEO];
[vwRemote setUserInteractionEnabled:NO];
[vwRemote setHidden:YES];
[baseView addSubview:vwRemote];
SKWVideo* vwLocal = [[SKWVideo alloc] initWithFrame:rcLocal];
[vwLocal setBackgroundColorUIColor clearColor]];
[vwLocal setTag:TAG_LOCAL_VIDEO];
[baseView addSubview:vwLocal];
// Add local stream to local video view
[vwLocal addSrc:_msLocal track:0];
//////////// END: Add Remote & Local SKWVideo to View /////////////
这是一个例子:
Mage::getSingleton('core/resource_iterator')
->walk(
$query->getSelect(),
array(array($this,'callbackFunction')));
快乐的编码, 亚当
答案 2 :(得分:0)
我不是magento的专家,但也许是因为该系列除了数字之外还有不同的键?尝试使用print_r打印出该集合,以查看该对象具有哪些键。
如果您需要使用数字进行迭代,您可以随时执行以下操作:
$i=0;
foreach($collection as $product)
{
$sku = $product->getSku();
$i++;
}
编辑:无论如何,似乎集合不是常规数组,所以你不能像你尝试的那样使用它们。
答案 3 :(得分:0)
$array = array(
"foo" => "bar",
"bar" => "foo",
);
您必须使用的索引无法访问此类型的数组
$array["foo"];
如果密钥不可预测,您必须使用
`的foreach
答案 4 :(得分:0)
<?php
$collection=array("book1"=>"bat","book2"=>"cat");
$collectionLength = count($collection);
for($j = 0; $j < $collectionLength; $j++)
{
$productFromStore = $collection[$j];
echo $productFromStore; //prints nothing !
}
foreach($collection as $var)
{
echo $var; //prints batcat
}
答案 5 :(得分:-1)
在magento集合中以对象的形式返回。使用下面的代码获取SKU和NAME。或者使用print_r($collection->getData())
以数组Key =&gt;值格式获取数据。
foreach($collection as $productCollection){
$sku = $productCollection->getSku();
$name = $productCollection->getName();
}