| 
<?
// Some error codes...
 define( "ERROR_CODE_OK", 0 );
 define( "ERROR_CODE_1", 1 );
 define( "ERROR_CODE_2", 2 );
 define( "ERROR_CODE_3", 3 );
 
 //
 //  View errors and warnings with no enhancement...
 //
 ?>
 <p>
 <b>Errors and warnings with normal (non production site) error/warning method calls</b>:
 </p>
 <?
 $cls = new existing_class();
 $foocls = new existing_class();
 
 // It works for includes too...
 include( "example2.php" );
 
 $cls->set_error( ERROR_CODE_1, "Error in global scope..." );
 display_class_error();
 
 func_set_error( ERROR_CODE_2, "Error set in a function..." );
 display_class_error();
 
 inc_func_set_error( ERROR_CODE_3, "Error set in a function from an included file..." );
 display_class_error();
 
 $cls->add_warning( "Warning with no tag." );
 
 foobar( 1, $foocls );
 
 if( ($fs = @fopen( __FILE__, "r" )) )
 {
 foobar2( $fs );
 fclose( $fs );
 }
 
 foobar2( $foocls );
 
 if( $cls->has_warnings() )
 {
 ?>
 <p>
 <b>GENERAL WARNINGS</b>:<br/>
 <pre><? print_r( $cls->get_warnings() ); ?></pre>
 </p>
 <?
 
 if( $cls->has_warnings( "FUNC_WARNING" ) )
 {
 ?>
 <p>
 <b>FUNCTION WARNINGS</b>:<br/>
 <pre><? print_r( $cls->get_warnings( "FUNC_WARNING" ) ); ?></pre>
 </p>
 <?
 }
 }
 
 //
 //  Use debug enhancement class...
 //
 ?>
 <p><hr /></p>
 <?
 // Only thing to do if we need enhanced debugging is include phs_error.inc.php
 include( "phs_error.inc.php" );
 
 ?>
 <p>
 <b>Static method call example</b>:<br/>
 Note that you won't get <code><b>existing_class::_static_call_trace()</b></code> as result, but <code><b>prototype_class::_static_call_trace()</b></code> as you cannot obtain class name of child from a static call (yet).<br/>
 <pre><?=do_static_call()?></pre>
 </p>
 
 <p>
 <b>Errors and warnings using PHS_Error class</b>:
 </p>
 <?
 
 $cls = new existing_class();
 $foocls = new existing_class();
 
 // It works for includes too...
 include( "example2.php" );
 
 $cls->set_error( ERROR_CODE_1, "Error in global scope..." );
 display_class_error();
 
 func_set_error( ERROR_CODE_2, "Error set in a function..." );
 display_class_error();
 
 inc_func_set_error( ERROR_CODE_3, "Error set in a function from an included file..." );
 display_class_error();
 
 $cls->add_warning( "Warning with no tag." );
 
 foobar( 1, $foocls );
 
 if( ($fs = @fopen( __FILE__, "r" )) )
 {
 foobar2( $fs );
 fclose( $fs );
 }
 
 foobar2( $foocls );
 
 if( $cls->has_warnings() )
 {
 $class_warnings = $cls->get_warnings();
 ?>
 <p>
 <b>GENERAL WARNINGS</b>:<br/>
 
 <pre><? print_r( $class_warnings ); ?></pre>
 </p>
 <?
 
 if( $cls->has_warnings( "FUNC_WARNING" ) )
 {
 $class_warnings = $cls->get_warnings( "FUNC_WARNING" );
 ?>
 <p>
 <b>FUNCTION WARNINGS</b>:<br/>
 <pre><? print_r( $class_warnings ); ?></pre>
 </p>
 <?
 }
 }
 
 //
 //  Some function definitions...
 //
 function do_static_call()
 {
 return existing_class::_static_call_trace();
 }
 
 function foobar( $a, $b )
 {
 global $cls;
 
 $cls->add_warning( "Demonstrate how class backtraces function calls", "FUNC_WARNING" );
 }
 
 function foobar2( $a )
 {
 global $cls;
 
 $cls->add_warning( "Demonstrate how class backtraces function calls", "FUNC_WARNING" );
 }
 
 function func_set_error( $code, $msg )
 {
 global $cls;
 
 $cls->set_error( $code, $msg );
 }
 
 function display_class_error()
 {
 global $cls;
 
 // Checking class for errors...
 if( $cls->has_error() )
 {
 $error = $cls->get_error();
 ?>
 <p>
 <pre><?=$error["error_msg"]?></pre>
 </p>
 <?
 }
 }
 
 //
 //  "Prototype" class which defines error/warning methods for child classes
 //
 class prototype_class
 {
 //! Holds error class object
 var $use_error_class;
 
 //! Error code and error message
 var $error_no, $error_msg;
 
 //! Warnings...
 var $warnings;
 
 function prototype_class()
 {
 if( @class_exists( "PHS_Error" ) )
 {
 $this->use_error_class = new PHS_Error( ERROR_CODE_OK, "Class inited" );
 } else
 $this->use_error_class = false;
 
 $this->warnings = false;
 $this->set_error( ERROR_CODE_OK, "Class inited" );
 }
 
 function _static_call_trace()
 {
 if( @class_exists( "PHS_Error" ) )
 return PHS_Error::debug_call_backtrace();
 }
 
 function set_error( $error_no, $error_msg )
 {
 if( is_object( $this->use_error_class ) )
 {
 // for internal use keep error code and msg in variables...
 $this->error_no = $error_no;
 $this->error_msg = $error_msg;
 
 $this->use_error_class->set_error( $error_no, $error_msg );
 } else
 {
 $this->error_no = $error_no;
 $this->error_msg = $error_msg;
 }
 }
 
 function has_error()
 {
 if( is_object( $this->use_error_class ) )
 return $this->use_error_class->has_error();
 else
 return array( "error_msg" => $this->error_msg, "error_no" => $this->error_no );
 }
 
 function get_error()
 {
 if( is_object( $this->use_error_class ) )
 return $this->use_error_class->get_error();
 else
 return array( "error_msg" => $this->error_msg, "error_no" => $this->error_no );
 }
 
 function add_warning( $warning, $tag = false )
 {
 if( is_object( $this->use_error_class ) )
 {
 $this->use_error_class->add_warning( $warning, $tag );
 $this->warnings = true;
 } else
 {
 if( $this->warnings === false )
 $this->warnings = array();
 
 if( !empty( $tag ) )
 {
 if( !isset( $this->warnings[$tag] ) )
 $this->warnings[$tag] = array();
 
 $this->warnings[$tag][] = $warning;
 } else
 $this->warnings[] = $warning;
 }
 }
 
 //! \brief Tells if class has any warrnings (in total or for a specific tag)
 /**
 *  Tells if class has any warnings for a tag or in total.
 *
 *  \param (mixed) $tag false for total number of warnings or string/int for specific tag
 *  \return (int) Number of warnings (in total or for a specific tag)
 */
 function has_warnings( $tag = false )
 {
 if( is_object( $this->use_error_class ) )
 return $this->use_error_class->has_warnings( $tag );
 
 else
 {
 if( $tag === false )
 {
 if( $this->warnings !== false )
 return count( $this->warnings );
 else
 return 0;
 } elseif( isset( $this->warnings[$tag] ) and is_array( $this->warnings[$tag] ) )
 return count( $this->warnings[$tag] );
 else
 return 0;
 }
 }
 
 //! \brief Get warnings for current instance of class
 /**
 *  Get warnings for current instance of class
 *  \return (mixed) Array of warning messages or false if no warning
 */
 function get_warnings( $tag = false )
 {
 if( $this->warnings === false )
 return false;
 
 if( is_object( $this->use_error_class ) )
 return $this->use_error_class->get_warnings( $tag );
 
 if( $this->warnings === false
 or ($tag !== false and !isset( $this->warnings[$tag] )) )
 return false;
 
 $ret_warnings = array();
 
 if( $tag === false )
 $warning_pool = $this->warnings;
 else
 $warning_pool = $this->warnings[$tag];
 
 foreach( $warning_pool as $wtag => $warning )
 {
 if( is_array( $warning ) )
 {
 foreach( $warning as $junk => $value )
 $ret_warnings[] = "[".$wtag."] ".$value;
 } else
 $ret_warnings[] = $warning;
 }
 
 return $ret_warnings;
 }
 
 }
 
 //
 //  Class definition
 //
 // You can easily debug your existing classes by deriving a "prototype" class...
 class existing_class extends prototype_class
 {
 function existing_class()
 {
 $this->prototype_class();
 }
 
 function some_method()
 {
 $this->set_error( ERROR_CODE_3, "Existing class." );
 }
 }
 
 ?>
 |