我正在运行Magento 1.4,但也在1.7中验证了这个问题.
使用实例Varien_Data_Collection提供了使用Varien_Data_Collection::removeItemByKey.在我的情况下,我正在从集合中删除项目,然后尝试获取该集合的更新大小,如下所示:
$body=$this->getTable()->getBody();
echo $body->getHeight(); // Outputs 25
$body->deleteRow(1);
echo $body->getHeight(); // Still outputs 25
...
My_Model_Body_Class extends Mage_Core_Model_Abstract {
/* @var $_rows Varien_Data_Collection */
protected $_rows;
public function deleteRow($index) {
$this->_rows->removeItemByKey($index);
return $this;
}
public function getHeight() {
return $this->_rows->getSize();
}
}
...
Run Code Online (Sandbox Code Playgroud)
代码限制简洁.
因此,如果您调用我的deleteRow方法,该项目实际上将从集合中删除,但后续调用以获取该集合的大小将始终返回原始计数.因此,如果我在集合中有25个项目,并删除1,那么getSize对集合的调用将返回25.
我将其追溯到父类,在Varien_Data_Collection::getSize:
/**
* Retrieve collection all items count
*
* @return int
*/
public function getSize()
{
$this->load();
if (is_null($this->_totalRecords)) {
$this->_totalRecords = count($this->getItems());
}
return intval($this->_totalRecords);
}
Run Code Online (Sandbox Code Playgroud)
我们看到计数取决于_totalRecords属性的NULL状态.所以它看起来像核心代码中的一个错误.我读得对吗?我应该只依靠对count物品的电话吗?
我们看到计数取决于
_totalRecords属性的NULL状态.所以它看起来像核心代码中的一个错误.我读得对吗?
是否将所述行为解释为错误或特征,取决于旁观者的眼睛.
这个行为不是1.4具体的,顺便说一下; 它的工作方式与当前的CE版本(1.8.1)相同.
public function getSize()
{
$this->load();
if (is_null($this->_totalRecords)) {
$this->_totalRecords = count($this->getItems());
}
return intval($this->_totalRecords);
}
Run Code Online (Sandbox Code Playgroud)
大多数人肯定希望一个名为getSize()always 的方法总是返回当前大小,所以他们可能会把它称为bug.
但是如果你仔细看看这个Varien_Data_Collection课程,你会注意到,这getSize()不是唯一看起来有点像......"怪异"的方法.
例如,采用addItem()和removeItemByKey()方法.
_totalRecords当getSize()使用它时,为什么不增加/减少属性?
这些"怪异"行为的原因是,它Varien_Data_Collection基本上是为使用延迟加载模式而设计的.这意味着,它允许延迟加载集合,直到真正需要数据.
要实现此目的,请Varien_Data_Collection实现IteratorAggregate和Countable接口.他们的实施要点是getIterator()和count()方法:
public function getIterator()
{
$this->load();
return new ArrayIterator($this->_items);
}
public function count()
{
$this->load();
return count($this->_items);
}
Run Code Online (Sandbox Code Playgroud)
如您所见,这两种方法都load()首先调用.
结果是,无论何时使用集合上的foreachPHP函数count(),load()都会自动调用该方法.
现在,对于默认Varien_Data_Collection情况,load()调用时不会发生任何特殊情况,因为load()只有调用loadData()且loadData()只返回$this.
但是当涉及到其使用频繁的子类时Varien_Data_Collection_Db,调用load()将导致加载集合并设置_totalRecords为已count加载记录的SQL .
出于性能原因,集合通常仅加载一次(如果尚未加载).
所以你看,根据你使用的上下文Varien_Data_Collection,它完全有意义,为什么getSize()这样做.
我应该只依靠对
count物品的电话吗?
如果您的收藏不受复杂或缓慢的I/O限制,我会说:是的.
你可以简单地使用:
$n = count($this->_rows->getItems());
Run Code Online (Sandbox Code Playgroud)
甚至这样:
$n = count($this->_rows->getIterator());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1621 次 |
| 最近记录: |