⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 recursiveiteratoriterator.inc

📁 PHP v6.0 For Linux 运行环境:Win9X/ WinME/ WinNT/ Win2K/ WinXP
💻 INC
字号:
<?php

/** @file recursiveiteratoriterator.inc * @ingroup SPL * @brief class RecursiveIteratorIterator * @author  Marcus Boerger * @date    2003 - 2006 * * SPL - Standard PHP Library *//**
 * @brief   Iterates through recursive iterators
 * @author  Marcus Boerger
 * @version 1.3
 * @since PHP 5.0
 *
 * The objects of this class are created by instances of RecursiveIterator. 
 * Elements of those iterators may be traversable themselves. If so these 
 * sub elements are recursed into.
 */
class RecursiveIteratorIterator implements OuterIterator
{
	/** Mode: Only show leaves */
	const LEAVES_ONLY 		= 0;
	/** Mode: Show parents prior to their children */
	const SELF_FIRST		= 1;
	/** Mode: Show all children prior to their parent */
	const CHILD_FIRST		= 2;

	/** Flag: Catches exceptions during getChildren() calls and simply jumps
	 * to the next element. */
	const CATCH_GET_CHILD	= 0x00000002;

	private $ait   = array();
	private $level = 0;
	private $mode  = self::LEAVES_ONLY;
	private $flags = 0;
	private $max_depth = -1;

	/** Construct from RecursiveIterator
	 *
	 * @param it     RecursiveIterator to iterate
	 * @param mode   Operation mode (one of):
	 *               - LEAVES_ONLY only show leaves
	 *               - SELF_FIRST  show parents prior to their childs
	 *               - CHILD_FIRST show all children prior to their parent
	 * @param flags  Control flags, zero or any combination of the following
	 *               (since PHP 5.1).
	 *               - CATCH_GET_CHILD which catches exceptions during
	 *                 getChildren() calls and simply jumps to the next 
	 *                 element.
	 */
	function __construct(RecursiveIterator $it, $mode = self::LEAVES_ONLY, $flags = 0)
	{
		$this->ait[0] = $it;
		$this->mode   = $mode;
		$this->flags  = $flags;
	}

	/** Rewind to top iterator as set in constructor
	 */
	function rewind()
	{
		while ($this->level) {
			unset($this->ait[$this->level--]);
			$this->endChildren();
		}
		$this->ait[0]->rewind();
		$this->ait[0]->recursed = false;
		callNextElement(true);
	}
	
	/** @return whether iterator is valid
	 */
	function valid()
	{
		$level = $this->level;
		while ($level >= 0) {
			$it = $this->ait[$level];
			if ($it->valid()) {
				return true;
			}
			$level--;
			$this->endChildren();
		}
		return false;
	}
	
	/** @return current key
	 */
	function key()
	{
		$it = $this->ait[$this->level];
		return $it->key();
	}
	
	/** @return current element
	 */
	function current()
	{
		$it = $this->ait[$this->level];
		return $it->current();
	}
	
	/** Forward to next element
	 */
	function next()
	{
		while ($this->level >= 0) {
			$it = $this->ait[$this->level];
			if ($it->valid()) {
				if (!$it->recursed && callHasChildren()) {
					if ($this->max_depth == -1 || $this->max_depth > $this->level) {
						$it->recursed = true;
						try
						{
							$sub = callGetChildren();
						}
						catch (Exception $e)
						{
							if (!($this->flags & self::CATCH_GET_CHILD))
							{
								throw $e;
							}
							$it->next();
							continue;
						}
						$sub->recursed = false;
						$sub->rewind();
						if ($sub->valid()) {
							$this->ait[++$this->level] = $sub;
							if (!$sub instanceof RecursiveIterator) {
								throw new Exception(get_class($sub).'::getChildren() must return an object that implements RecursiveIterator');
							}
							$this->beginChildren();
							return;
						}
						unset($sub);
					}
					else
					{
						/* do not recurse because of depth restriction */
						if ($this->flages & self::LEVAES_ONLY)
						{
							$it->next();
							continue;
						}
						else
						{
							return; // we want the parent
						}
					}
					$it->next();
					$it->recursed = false;
					if ($it->valid()) {
						return;
					}
					$it->recursed = false;
				}
			}
			else if ($this->level > 0) {
				unset($this->ait[$this->level--]);
				$it = $this->ait[$this->level];
				$this->endChildren();
				callNextElement(false);
			}
		}
		callNextElement(true);
	}

	/** @return Sub Iterator at given level or if unspecified the current sub 
	 *          Iterator
	 */
	function getSubIterator($level = NULL)
	{
		if (is_null($level)) {
			$level = $this->level;
		}
		return @$this->ait[$level];
	}

	/**
	 * @return The inner iterator
	 */	
	function getInnerIterator()
	{
		return $this->it;
	}

	/** @return Current Depth (Number of parents)
	 */
	function getDepth()
	{
		return $this->level;
	}

	/** @return whether current sub iterators current element has children
	 * @since PHP 5.1
	 */
	function callHasChildren()
	{
		return $this->ait[$this->level]->hasChildren();
	}

	/** @return current sub iterators current children
	 * @since PHP 5.1
	 */
	function callGetChildren()
	{
		return $this->ait[$this->level]->getChildren();
	}

	/** Called right after calling getChildren() and its rewind().
	 * @since PHP 5.1
	 */
	function beginChildren()
	{
	}
	
	/** Called after current child iterator is invalid and right before it
	 * gets destructed.
	 * @since PHP 5.1
	 */
	function endChildren()
	{
	}

	private function callNextElement($after_move)
	{
		if ($this->valid())
		{
			if ($after_move)
			{
				if (($this->mode == self::SELF_FIRST && $this->callHasChildren())
				     $this->mode == self::LEAVES_ONLY)
				$this->nextElement();
			}
			else
			{
				$this->nextElement();
			}
		}
	}
	
	/** Called when the next element is available
	 */
	function nextElement();

	/** @param max_depth new maximum allowed depth or -1 for any depth
	 */
	function setMaxDepth($max_depth = -1)
	{
		$max_depth = (int)$max_depth;
		if ($max_depth < -1) {
			throw new OutOfRangeException('Parameter max_depth must be >= -1');
		}
		$this->max_depth = $max_depth;
	}
	
	/** @return maximum allowed depth or false if any depth is allowed
	 */
	function getMaxDepth()
	{
		return $this->max_depth == -1 ? false : $this->max_depth;
	}
}

?>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -