2013-03-11 79 views
9

这可能是一个简单的问题,但我找不到答案。我怎么知道我的收藏没有数据?检测收集是否包含数据

我做$datas = Mage::getModel('zzz/zzz')->getCollection()如果我做了一个$datas->getData()它返回一个空数组,但是如何知道我的集合没有数据而没有执行foreach或getData?

回答

20

您应该避免使用count或您的收藏夹。这里的原因:

Mage_Core_Model_Resource_Db_Collection_Abstract(即几乎所有的Magento收藏继承系列型号)没有count()定义,因此使用count您收集你最有可能与Varien_Data_Collection::count()这是非常糟糕的选择结束了,因为它做一个集合load(),然后计算所加载的对象:

/** 
* Retireve count of collection loaded items 
* 
* @return int 
*/ 
public function count() 
{ 
    $this->load(); 
    return count($this->_items); 
} 

具有大集合(尤其是EAV集合)将导致加载所有您的收藏数据 - 这可能需要大量的时间。

相反,你应该使用Varien_Data_Collection_Db::getSize()方法,该方法将运行SQL查询来获取只计算,更优化,相比检索所有类型的数据进行收集负载:

/** 
* Get collection size 
* 
* @return int 
*/ 
public function getSize() 
{ 
    if (is_null($this->_totalRecords)) { 
     $sql = $this->getSelectCountSql(); 
     $this->_totalRecords = $this->getConnection()->fetchOne($sql, $this->_bindParams); 
    } 
    return intval($this->_totalRecords); 
} 

除此之外,后load收集不能以任何方式修改。例如,在使用count()之后,您将无法在任何时候应用更改排序顺序的其他过滤器。

所以,正确的答案应该是:

$collection = Mage::getModel('zzz/zzz')->getCollection(); 
var_dump($collection->getSize()); 
+0

感谢这非常详细的答案!接受! – Shadowbob 2013-03-11 17:31:19

+0

我真的想收藏这个答案。或添加到列表中,在我的个人资料中,我可以保留像这样的宝贵答案。 – 2014-12-01 09:24:15

1

你可以使用;

$collection = Mage::getModel('zzz/zzz')->getCollection(); 
var_dump($collection->count()); 
+0

它的工作!我不知道我们可以数。非常感谢。 – Shadowbob 2013-03-11 16:25:53

+2

@ user1682624,你应该避免在集合中使用'count()'方法。我解释了为什么在我的文章 – 2013-03-11 17:08:51

4

您可以轻松地只是做一个if语句,像这样:

if (!$datas->getData() || empty($datas->getData())) { 
    // do things 
} 
+0

对不起,这是我想避免的事情,我+1的答案。谢谢。 – Shadowbob 2013-03-11 16:26:51

2

/** * 检索集合中的所有项目数 * * @返回INT */ $集合=法师:: getModel( 'AAA/BBB') - > getCollection() - >的getSize();

这是在分页等使用的代码,并建议。

那里收集加载项) /** * 计数Retireve * * @返回INT */ 公共函数count(

会检查加载的项目有用的数据。

1

运行在集合上进行简单,标准的PHP count()是在这里很好。只要你已经适当地过滤了你的收藏集,你应该在完成收集之前总是这样做,在集合上调用->count()方法也没问题。只要你操控以任何方式收集,它会不管你使用的方法,所以一个标准的PHP count()的加载,调用该对象的->count()方法,通过与foreach()集合运行后会加载所有的集合在同一方式为load(),其实如果你跟踪load()方法后面,你会看到它实际上是运行在标准的PHP foreach()加载收集数据。

所以它不会不管你怎么做,你还不能指望你的收藏,直到你知道有多少结果已经从数据库返回,因此上述方法是好的,但并不意味着额外的DB调用,首先要计数,然后加载。一个更好的方法是确保您通过WHERE条款等缩小它们使您的SELECT报表尽可能具体。如果从集合拉选择对象,你可以访问所有的here所示的Zend_Db_Select对象方法,即

$collection->getSelect()->where('......... = ?', $var);

+0

事实上,它只会返回1个数据或空的,所以我正在寻找最快的方法来做到这一点。 – Shadowbob 2013-03-12 10:04:10

+0

嗨乔纳森,谢谢你的回答。正如您正确识别,收集将最终加载。唯一的问题是:我们大多数时候使用'getSize'来标识,实际上我们是否需要加载它。 getSize的最典型用法是检查我们的集合实际上是否包含对象,然后继续执行(如果是)或者停止执行逻辑(因此集合将不会被加载)。除此之外,Collection可以被几个不同的模块用来准备它,所以在一个中使用'count'会破坏另一个的逻辑(查看目录工具栏) – 2013-03-12 15:01:32

0

假设该产品集为$ pro_collection

现在应用下面的代码..

<?php 
if(isset($pro_collection) && count($pro_collection) > 0) { 
    /* Your code here */ 
} 
?> 
1

除了公认的答案见基准测试:

特STED 750个产品

$collection->getData()

  • 总计已包含。壁挂时间(微秒):67,567微秒
  • 总计Incl。 CPU(微秒):67,599微秒
  • 总计Incl。 MemUse(字节):11,719,168字节
  • Total Incl。 PeakMemUse(字节):11648152个字节
  • 函数的调用次数:1047

$collection->getSize()

  • 总计已包含。壁挂时间(微秒):6,371微秒
  • 总计Incl。 CPU(微秒):4,402微秒
  • 总计Incl。 MemUse(字节):140,816字节
  • Total Incl。 PeakMemUse(字节):96000个字节
  • 函数的调用次数:191

$collection->count()sizeof($collection)

  • 总计已包含。壁挂时间(微秒):2,130,568微秒
  • 总数包含CPU(微秒):2,080,617微秒
  • 总数包含MemUse(字节):12,899,872字节
  • Total Incl。PeakMemUse(字节):13002256个字节
  • 函数的调用次数:101073

所以,你应该用getSize()去。


形式:https://magento.stackexchange.com/questions/179028/how-to-check-if-a-collection-has-items/179035#179035