xref: /PHP-5.5/ext/spl/examples/class_tree.php (revision cd2953db)
1<?php
2
3/** @file   class_tree.php
4 * @brief   Class Tree example
5 * @ingroup Examples
6 * @author  Marcus Boerger
7 * @date    2003 - 2008
8 * @version 1.1
9 *
10 * Usage: php class_tree.php \<class\>
11 *
12 * Simply specify the root class or interface to tree with parameter \<class\>.
13 */
14
15if ($argc < 2) {
16	echo <<<EOF
17Usage: php ${_SERVER['PHP_SELF']} <class>
18
19Displays a graphical tree for the given <class>.
20
21<class> The class or interface for which to generate the tree graph.
22
23
24EOF;
25	exit(1);
26}
27
28if (!class_exists("RecursiveTreeIterator", false)) require_once("recursivetreeiterator.inc");
29
30/** \brief Collects sub classes for given class or interface
31 */
32class SubClasses extends RecursiveArrayIterator
33{
34	/** @param base  base class to collect sub classes for
35	 * @param check_interfaces whether we deal with interfaces
36	 */
37	function __construct($base, $check_interfaces = false)
38	{
39		foreach(get_declared_classes() as $cname)
40		{
41			$parent = get_parent_class($cname);
42			if (strcasecmp($parent, $base) == 0)
43			{
44				$this->offsetSet($cname, new SubClasses($cname));
45			}
46			if ($check_interfaces)
47			{
48				if ($parent)
49				{
50					$parent_imp = class_implements($parent);
51				}
52				foreach(class_implements($cname) as $iname)
53				{
54					if (strcasecmp($iname, $base) == 0)
55					{
56						if (!$parent || !in_array($iname, $parent_imp))
57						{
58							$this->offsetSet($cname, new SubClasses($cname));
59						}
60					}
61				}
62			}
63		}
64		if ($check_interfaces)
65		{
66			foreach(get_declared_interfaces() as $cname)
67			{
68				foreach(class_implements($cname) as $iname)
69				{
70					if (strcasecmp($iname, $base) == 0)
71					{
72						$this->offsetSet($cname, new SubClasses($cname, true));
73					}
74				}
75			}
76		}
77		$this->uksort('strnatcasecmp');
78	}
79
80	/** @return key() since that is the name we need
81	 */
82	function current()
83	{
84		$result = parent::key();
85		$parent = get_parent_class($result);
86		if ($parent)
87		{
88			$interfaces = array_diff(class_implements($result), class_implements($parent));
89			if ($interfaces)
90			{
91				$implements = array();
92				foreach($interfaces as $interface)
93				{
94					$implements = array_merge($implements, class_implements($interface));
95				}
96				$interfaces = array_diff($interfaces, $implements);
97				natcasesort($interfaces);
98				$result .= ' (' . join(', ', $interfaces) . ')';
99			}
100		}
101		return $result;
102	}
103}
104
105$it = new RecursiveTreeIterator(new SubClasses($argv[1], true));
106
107echo $argv[1]."\n";
108foreach($it as $c=>$v)
109{
110	echo "$v\n";
111}
112
113?>