From: Chuck Hagenbuch Date: Fri, 21 Aug 2009 17:48:27 +0000 (-0400) Subject: start working on Horde_Support_Backtrace, an object to make it easier to get pieces... X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=6ddf57a818b5b6ed6d56e058952dfaf0f398fc32;p=horde.git start working on Horde_Support_Backtrace, an object to make it easier to get pieces of the calling history --- diff --git a/framework/Support/lib/Horde/Support/Backtrace.php b/framework/Support/lib/Horde/Support/Backtrace.php new file mode 100644 index 000000000..7d56c4405 --- /dev/null +++ b/framework/Support/lib/Horde/Support/Backtrace.php @@ -0,0 +1,111 @@ +createFromException($backtrace); + } elseif ($backtrace) { + $this->createFromDebugBacktrace($backtrace); + } else { + $this->createFromDebugBacktrace(debug_backtrace(), 1); + } + } + + /** + * Wrap the result of debug_backtrace(). By specifying a non-zero + * $nestingLevel, levels of the backtrace can be ignored. For instance, when + * Horde_Support_Backtrace creates a backtrace for you, it ignores the + * Horde_Backtrace constructor in the wrapped trace. + * + * @param array $backtrace The debug_backtrace() result + * @param integer $nestingLevel The number of levels of the backtrace to ignore. + */ + public function createFromDebugBacktrace($backtrace, $nestingLevel = 0) + { + while ($nestingLevel > 0) { + array_shift($backtrace); + --$nestingLevel; + } + + $this->_backtrace = $backtrace; + } + + /** + * Wrap an Exception object's backtrace + * + * @param Exception $e The exception to wrap + */ + public function createFromException(Exception $e) + { + $this->_backtrace = $e->getTrace(); + } + + /** + * Return the nesting level (number of calls deep) of the current context. + * + * @return integer Nesting level + */ + public function getNestingLevel() + { + return count($this->_backtrace); + } + + /** + * Return the context at a specific nesting level. + * + * @param integer $nestingLevel 0 == current level, 1 == caller, and so on + * + * @return array The requested context + */ + public function getContext($nestingLevel) + { + if (!isset($this->_backtrace[$nestingLevel])) { + throw new Horde_Exception('Unknown nesting level'); + } + return $this->_backtrace[$nestingLevel]; + } + + /** + * Return details about the caller of the routine where the exception + * occurred + * + * @return array $caller + */ + public function getCurrentContext() + { + return $this->getContext(0); + } + + /** + * Return details about the caller of the routine where the exception + * occurred + * + * @return array $caller + */ + public function getCallingContext() + { + return $this->getContext(1); + } +} diff --git a/framework/Support/package.xml b/framework/Support/package.xml index d88274013..4b6704fb9 100644 --- a/framework/Support/package.xml +++ b/framework/Support/package.xml @@ -27,6 +27,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> * Initial horde/support package * Initial Horde_Support_Array object + * Initial Horde_Support_Backtrace object * Initial Horde_Support_ConsistentHash object * Initial Horde_Support_Inflector object * Initial Horde_Support_Stack object @@ -47,6 +48,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> + @@ -72,6 +74,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> + diff --git a/framework/Support/test/Horde/Support/BacktraceTest.php b/framework/Support/test/Horde/Support/BacktraceTest.php new file mode 100644 index 000000000..5dd4f3bb0 --- /dev/null +++ b/framework/Support/test/Horde/Support/BacktraceTest.php @@ -0,0 +1,82 @@ +getCurrentContext(); + $this->assertEquals(__FUNCTION__, $caller['function']); + + $caller = $trace->getCallingContext(); + $this->assertEquals('invoke', $caller['function']); + } + + public function testCreateFromGeneratedBacktrace() + { + $trace = new Horde_Support_Backtrace($this->returnBacktrace()); + + $caller = $trace->getCurrentContext(); + $this->assertEquals('returnBacktrace', $caller['function']); + + $caller = $trace->getCallingContext(); + $this->assertEquals(__FUNCTION__, $caller['function']); + } + + public function testCreateFromException() + { + try { + $this->throwException(); + } catch (Exception $e) { + } + + $trace = new Horde_Support_Backtrace($e); + + $caller = $trace->getCurrentContext(); + $this->assertEquals('throwException', $caller['function']); + + $caller = $trace->getCallingContext(); + $this->assertEquals(__FUNCTION__, $caller['function']); + } + + public function testNestingLevelOfDefaultVsGeneratedBacktrace() + { + $t1 = new Horde_Support_Backtrace(); + $t2 = new Horde_Support_Backtrace($this->returnBacktrace()); + + $this->assertEquals($t1->getCurrentContext(), $t2->getCallingContext()); + } + + public function testNestingLevel() + { + $backtrace = new Horde_Support_Backtrace(); + $dbt = debug_backtrace(); + $this->assertEquals(count($dbt), $backtrace->getNestingLevel()); + } + + public function returnBacktrace() + { + return debug_backtrace(); + } + + public function throwException() + { + throw new Exception(); + } +}