我创建了一个扩展的自定义迭代器,RecursiveIteratorIterator
我用它来迭代Doctrine_Collection
使用该NestedSet
行为的表中的 a (例如,以便我将自定义排序应用于层次结构中每个级别的记录)。
我的项目中有几个模型利用了这个迭代器,所以我创建了一个如下所示的基类:
/** Base functionality for iterators designed to iterate over nested set
* structures.
*/
abstract class BaseHierarchyIterator
extends RecursiveIteratorIterator
{
/** Returns the component name that the iterator is designed to work with.
*
* @return string
*/
abstract public function getComponentName( );
/** Inits the class instance.
*
* @param $objects Doctrine_Collection Assumed to already be sorted by `lft`.
*
* @throws LogicException If $objects is a collection from the wrong table.
*/
public function __construct( Doctrine_Collection $objects )
{
/** @kludge Initialization will fail horribly if we invoke a subclass method
* before we have initialized the inner iterator.
*/
parent::__construct(new RecursiveArrayIterator(array()));
/* Make sure we have the correct collection type. */
$component = $this->getComponentName();
if( $objects->getTable()->getComponentName() != $component )
{
throw new LogicException(sprintf(
'%s can only iterate over %s collections.'
, get_class($this)
, $component
));
}
/* Build the array for the inner iterator. */
$top = array();
/** @var $object Doctrine_Record|Doctrine_Node_NestedSet */
foreach( $objects as $object )
{
// ... magic happens here ...
}
parent::__construct(
new RecursiveArrayIterator($top)
, RecursiveIteratorIterator::SELF_FIRST
);
}
...
}
子类可能看起来像这样:
/** Iterates hierarchically through a collection of User objects.
*/
class UserHierarchyIterator
extends BaseHierarchyIterator
{
/** Returns the component name that the iterator is designed to work with.
*
* @return string
*/
public function getComponentName()
{
return UserTable::getInstance()->getComponentName();
}
...
}
请注意@kludge
基类中构造函数顶部的 :
/** @kludge Initialization will fail horribly if we invoke a subclass method
* before we have initialized the inner iterator.
*/
parent::__construct(new RecursiveArrayIterator(array()));
只要我将额外的初始化行保留在基类构造函数的顶部,一切都会按预期工作。
但是,如果我删除/注释该行,一旦脚本执行到达,我就会收到以下错误$component = $this->getComponentName()
:
致命错误:BaseHierarchyIterator::__construct(): UserHierarchyIterator 实例未在第 21 行的 /path/to/BaseHierarchyIterator.class.php 中正确初始化。
或者,如果我删除调用的代码$this->getComponentName()
(以及随后的条件块),构造函数仍按预期运行(减去确保组件名称正确的检查)。
这个错误的根本原因是什么?这个问题有更好的解决方法吗?
PHP版本信息:
PHP 5.3.3 (cli)(构建:2012 年 7 月 3 日 16:40:30) 版权所有 (c) 1997-2010 PHP 集团 Zend Engine v2.3.0,版权所有 (c) 1998-2010 Zend Technologies 与 Suhosin v0.9.29,版权所有 (c) 2007,SektionEins GmbH